Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:50:14

0001 #include <DD4hep/DD4hepUnits.h>
0002 
0003 #include "DataFormats/Math/interface/deltaPhi.h"
0004 #include "DataFormats/Math/interface/GeantUnits.h"
0005 #include "DataFormats/Math/interface/Rounding.h"
0006 #include "Geometry/TrackerNumberingBuilder/interface/GeometricDet.h"
0007 #include "Geometry/TrackerNumberingBuilder/interface/TrackerShapeToBounds.h"
0008 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0009 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0010 #include "CondFormats/GeometryObjects/interface/PGeometricDet.h"
0011 
0012 #include <cfloat>
0013 #include <string>
0014 
0015 namespace {
0016 
0017   const std::string strue("true");
0018 
0019   template <typename DDView>
0020   double getDouble(const char* s, DDView const& ev) {
0021     DDValue val(s);
0022     std::vector<const DDsvalues_type*> result;
0023     ev.specificsV(result);
0024     std::vector<const DDsvalues_type*>::iterator it = result.begin();
0025     bool foundIt = false;
0026     for (; it != result.end(); ++it) {
0027       foundIt = DDfetch(*it, val);
0028       if (foundIt)
0029         break;
0030     }
0031     if (foundIt) {
0032       const std::vector<std::string>& temp = val.strings();
0033       if (temp.size() != 1) {
0034         throw cms::Exception("Configuration") << "I need 1 " << s << " tags";
0035       }
0036       return double(::atof(temp[0].c_str()));
0037     }
0038     return 0;
0039   }
0040 
0041   template <typename DDView>
0042   std::string getString(const char* s, DDView const& ev) {
0043     DDValue val(s);
0044     std::vector<const DDsvalues_type*> result;
0045     ev.specificsV(result);
0046     std::vector<const DDsvalues_type*>::iterator it = result.begin();
0047     bool foundIt = false;
0048     for (; it != result.end(); ++it) {
0049       foundIt = DDfetch(*it, val);
0050       if (foundIt)
0051         break;
0052     }
0053     if (foundIt) {
0054       const std::vector<std::string>& temp = val.strings();
0055       if (temp.size() != 1) {
0056         throw cms::Exception("Configuration") << "I need 1 " << s << " tags";
0057       }
0058       return temp[0];
0059     }
0060     return "NotFound";
0061   }
0062 }  // namespace
0063 
0064 /**
0065  * What to do in the destructor?
0066  * destroy all the daughters!
0067  */
0068 GeometricDet::~GeometricDet() { deleteComponents(); }
0069 
0070 /*
0071   Constructor from old DD Filtered view.
0072 */
0073 GeometricDet::GeometricDet(DDFilteredView* fv, GeometricEnumType type)
0074     : ddname_(fv->name()),
0075       type_(type),
0076       ddd_(),  // To remove after DetExtra is removed (not used)
0077       trans_(fv->translation()),
0078       rho_(trans_.Rho()),
0079       phi_(trans_.Phi()),
0080       rot_(fv->rotation()),
0081       shape_(cms::dd::name_from_value(cms::LegacySolidShapeMap, fv->shape())),
0082       params_(fv->parameters()),
0083       isFromDD4hep_(false) {
0084   //  workaround instead of this at initialization
0085   const DDFilteredView::nav_type& nt = fv->navPos();
0086   ddd_ = nav_type(nt.begin(), nt.end());
0087 
0088   // Only look for sensor-related info on sensor volumes!
0089   if (type_ == DetUnit) {
0090     radLength_ = getDouble("TrackerRadLength", *fv);
0091     xi_ = getDouble("TrackerXi", *fv);
0092     pixROCRows_ = getDouble("PixelROCRows", *fv);
0093     pixROCCols_ = getDouble("PixelROCCols", *fv);
0094     pixROCx_ = getDouble("PixelROC_X", *fv);
0095     pixROCy_ = getDouble("PixelROC_Y", *fv);
0096     stereo_ = (getString("TrackerStereoDetectors", *fv) == strue);
0097     isLowerSensor_ = (getString("TrackerLowerDetectors", *fv) == strue);
0098     isUpperSensor_ = (getString("TrackerUpperDetectors", *fv) == strue);
0099     isFirstSensor_ = (getString("TrackerFirstDetectors", *fv) == strue);
0100     isSecondSensor_ = (getString("TrackerSecondDetectors", *fv) == strue);
0101     siliconAPVNum_ = getDouble("SiliconAPVNumber", *fv);
0102   }
0103 }
0104 
0105 /*
0106   Constructor from DD4hep Filtered view.
0107 */
0108 GeometricDet::GeometricDet(cms::DDFilteredView* fv, GeometricEnumType type)
0109     : ddname_(dd4hep::dd::noNamespace(fv->name())),
0110       type_(type),
0111       ddd_(fv->navPos()),  // To remove after DetExtra is removed (not used)
0112       trans_((fv->translation()) / dd4hep::mm),
0113       rho_(trans_.Rho()),
0114       phi_(trans_.Phi()),
0115       rot_(fv->rotation()),
0116       shape_(fv->shape()),
0117       params_(computeLegacyShapeParameters(shape_, fv->solid())),
0118       isFromDD4hep_(true) {
0119   using namespace angle_units::operators;
0120   if (almostEqual(phi_, -1._pi, 10)) {
0121     phi_ = 1._pi;
0122     // Standardize phi values of |pi| to be always +pi instead of sometimes -pi.
0123   }
0124 
0125   // Only look for sensor-related info on sensor volumes!
0126   if (type_ == DetUnit) {
0127     // IT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0128     pixROCRows_ = fv->get<double>("PixelROCRows");
0129     pixROCCols_ = fv->get<double>("PixelROCCols");
0130     pixROCx_ = fv->get<double>("PixelROC_X");
0131     pixROCy_ = fv->get<double>("PixelROC_Y");
0132 
0133     // Phase 1 OT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0134     stereo_ = (fv->get<std::string_view>("TrackerStereoDetectors") == strue);
0135     siliconAPVNum_ = fv->get<double>("SiliconAPVNumber");
0136 
0137     // Phase 2 OT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0138     isLowerSensor_ = (fv->get<std::string_view>("TrackerLowerDetectors") == strue);
0139     isUpperSensor_ = (fv->get<std::string_view>("TrackerUpperDetectors") == strue);
0140     isFirstSensor_ = (fv->get<std::string_view>("TrackerFirstDetectors") == strue);
0141     isSecondSensor_ = (fv->get<std::string_view>("TrackerSecondDetectors") == strue);
0142 
0143     // All sensors: IT or OT, Phase 1 or Phase 2 (NB: critical part on perf)
0144     fv->findSpecPar("TrackerRadLength", "TrackerXi");
0145     radLength_ = fv->getNextValue("TrackerRadLength");
0146     xi_ = fv->getNextValue("TrackerXi");
0147   }
0148 }
0149 
0150 /*
0151   Constructor from persistent version (DB).
0152 */
0153 GeometricDet::GeometricDet(const PGeometricDet::Item& onePGD, GeometricEnumType type)
0154     : ddname_(onePGD._name),
0155       type_(type),
0156       ddd_(),
0157       geographicalID_(onePGD._geographicalID),
0158       trans_(onePGD._x, onePGD._y, onePGD._z),
0159       rho_(onePGD._rho),
0160       phi_(onePGD._phi),
0161       rot_(onePGD._a11,
0162            onePGD._a12,
0163            onePGD._a13,
0164            onePGD._a21,
0165            onePGD._a22,
0166            onePGD._a23,
0167            onePGD._a31,
0168            onePGD._a32,
0169            onePGD._a33),
0170       shape_(cms::dd::name_from_value(cms::LegacySolidShapeMap, static_cast<LegacySolidShape>(onePGD._shape))),
0171       params_(),
0172       radLength_(onePGD._radLength),
0173       xi_(onePGD._xi),
0174       pixROCRows_(onePGD._pixROCRows),
0175       pixROCCols_(onePGD._pixROCCols),
0176       pixROCx_(onePGD._pixROCx),
0177       pixROCy_(onePGD._pixROCy),
0178       stereo_(onePGD._stereo),
0179       siliconAPVNum_(onePGD._siliconAPVNum)
0180 // NB: what about new data members isLowerSensor_, isUpperSensor_, isFromDD4hep_?
0181 // They are presently not added to PGeometricDet (no change in info stored into DB).
0182 {
0183   // Solid shape parameters: only for box (1) and trapezoid (3)
0184   if (onePGD._shape == 1 || onePGD._shape == 3) {
0185     params_.reserve(11);
0186     params_.emplace_back(onePGD._params0);
0187     params_.emplace_back(onePGD._params1);
0188     params_.emplace_back(onePGD._params2);
0189     params_.emplace_back(onePGD._params3);
0190     params_.emplace_back(onePGD._params4);
0191     params_.emplace_back(onePGD._params5);
0192     params_.emplace_back(onePGD._params6);
0193     params_.emplace_back(onePGD._params7);
0194     params_.emplace_back(onePGD._params8);
0195     params_.emplace_back(onePGD._params9);
0196     params_.emplace_back(onePGD._params10);
0197   }
0198 
0199   ddd_.reserve(onePGD._numnt);
0200   ddd_.emplace_back(onePGD._nt0);
0201   ddd_.emplace_back(onePGD._nt1);
0202   ddd_.emplace_back(onePGD._nt2);
0203   ddd_.emplace_back(onePGD._nt3);
0204   if (onePGD._numnt > 4) {
0205     ddd_.emplace_back(onePGD._nt4);
0206     if (onePGD._numnt > 5) {
0207       ddd_.emplace_back(onePGD._nt5);
0208       if (onePGD._numnt > 6) {
0209         ddd_.emplace_back(onePGD._nt6);
0210         if (onePGD._numnt > 7) {
0211           ddd_.emplace_back(onePGD._nt7);
0212           if (onePGD._numnt > 8) {
0213             ddd_.emplace_back(onePGD._nt8);
0214             if (onePGD._numnt > 9) {
0215               ddd_.emplace_back(onePGD._nt9);
0216               if (onePGD._numnt > 10) {
0217                 ddd_.emplace_back(onePGD._nt10);
0218               }
0219             }
0220           }
0221         }
0222       }
0223     }
0224   }
0225 }
0226 
0227 std::unique_ptr<Bounds> GeometricDet::bounds() const {
0228   TrackerShapeToBounds shapeToBounds;
0229   return std::unique_ptr<Bounds>(shapeToBounds.buildBounds(shape_, params_));
0230 }
0231 
0232 GeometricDet::Position GeometricDet::positionBounds() const {
0233   Position pos_(static_cast<float>(geant_units::operators::convertMmToCm(trans_.x())),
0234                 static_cast<float>(geant_units::operators::convertMmToCm(trans_.y())),
0235                 static_cast<float>(geant_units::operators::convertMmToCm(trans_.z())));
0236   return pos_;
0237 }
0238 
0239 GeometricDet::Rotation GeometricDet::rotationBounds() const {
0240   Translation x, y, z;
0241   rot_.GetComponents(x, y, z);
0242   Rotation rotation_(float(x.X()),
0243                      float(x.Y()),
0244                      float(x.Z()),
0245                      float(y.X()),
0246                      float(y.Y()),
0247                      float(y.Z()),
0248                      float(z.X()),
0249                      float(z.Y()),
0250                      float(z.Z()));
0251   return rotation_;
0252 }
0253 
0254 GeometricDet::ConstGeometricDetContainer GeometricDet::deepComponents() const {
0255   // iterate on all the DESCENDANTS!!
0256   ConstGeometricDetContainer temp_;
0257   deepComponents(temp_);
0258   return temp_;
0259 }
0260 
0261 void GeometricDet::deepComponents(ConstGeometricDetContainer& cont) const {
0262   if (isLeaf())
0263     cont.emplace_back(this);
0264   else
0265     std::for_each(container_.begin(), container_.end(), [&](const GeometricDet* iDet) { iDet->deepComponents(cont); });
0266 }
0267 
0268 void GeometricDet::addComponents(GeometricDetContainer const& cont) {
0269   container_.reserve(container_.size() + cont.size());
0270   std::copy(cont.begin(), cont.end(), back_inserter(container_));
0271 }
0272 
0273 void GeometricDet::addComponents(ConstGeometricDetContainer const& cont) {
0274   container_.reserve(container_.size() + cont.size());
0275   std::copy(cont.begin(), cont.end(), back_inserter(container_));
0276 }
0277 
0278 void GeometricDet::addComponent(GeometricDet* det) { container_.emplace_back(det); }
0279 
0280 namespace {
0281   struct Deleter {
0282     void operator()(GeometricDet const* det) const { delete const_cast<GeometricDet*>(det); }
0283   };
0284 }  // namespace
0285 
0286 void GeometricDet::deleteComponents() {
0287   std::for_each(container_.begin(), container_.end(), Deleter());
0288   container_.clear();
0289 }
0290 
0291 /*
0292  * PRIVATE
0293  */
0294 
0295 /*
0296  * DD4hep.
0297  * Keep order and units of parameters same as old DD, to avoid numerous regressions.
0298  * Shape parameters of interest, and those to be stored in DB, are only from boxes, trapezoids, and tubs.
0299  * Hence, they are the only shapes treated here. 
0300  * params() will complain, if the parameters of any other shape are accessed.
0301  */
0302 std::vector<double> GeometricDet::computeLegacyShapeParameters(const cms::DDSolidShape& mySolidShape,
0303                                                                const dd4hep::Solid& mySolid) const {
0304   std::vector<double> myOldDDShapeParameters;
0305 
0306   // Box
0307   if (mySolidShape == cms::DDSolidShape::ddbox) {
0308     const dd4hep::Box& myBox = dd4hep::Box(mySolid);
0309     myOldDDShapeParameters = {(myBox.x()) / dd4hep::mm, (myBox.y()) / dd4hep::mm, (myBox.z()) / dd4hep::mm};
0310   }
0311 
0312   // Trapezoid
0313   else if (mySolidShape == cms::DDSolidShape::ddtrap) {
0314     const dd4hep::Trap& myTrap = dd4hep::Trap(mySolid);
0315     myOldDDShapeParameters = {(myTrap->GetDZ()) / dd4hep::mm,
0316                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetTheta())),
0317                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetPhi())),
0318                               (myTrap->GetH1()) / dd4hep::mm,
0319                               (myTrap->GetBl1()) / dd4hep::mm,
0320                               (myTrap->GetTl1()) / dd4hep::mm,
0321                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetAlpha1())),
0322                               (myTrap->GetH2()) / dd4hep::mm,
0323                               (myTrap->GetBl2()) / dd4hep::mm,
0324                               (myTrap->GetTl2()) / dd4hep::mm,
0325                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetAlpha2()))};
0326   }
0327 
0328   // Tub
0329   else if (mySolidShape == cms::DDSolidShape::ddtubs) {
0330     const dd4hep::Tube& myTube = dd4hep::Tube(mySolid);
0331     double phi1 = static_cast<double>(angle_units::operators::convertDegToRad(myTube->GetPhi1()));
0332     phi1 = cms_rounding::roundIfNear0(phi1);
0333     if (phi1 != 0.0) {
0334       using namespace angle0to2pi;
0335       phi1 = make0To2pi(phi1) - 2._pi;
0336       // Turn positive angle to negative
0337     }
0338     myOldDDShapeParameters = {
0339         (myTube->GetDz()) / dd4hep::mm,
0340         (myTube->GetRmin()) / dd4hep::mm,
0341         (myTube->GetRmax()) / dd4hep::mm,
0342         phi1,
0343         static_cast<double>(angle_units::operators::convertDegToRad(myTube->GetPhi2() - myTube->GetPhi1()))};
0344   }
0345 
0346   return myOldDDShapeParameters;
0347 }
0348 
0349 std::string GeometricDet::printNavType(int const* n, size_t sz) {
0350   std::ostringstream oss;
0351   oss << '(';
0352   for (int const* it = n; it != n + sz; ++it) {
0353     oss << *it << ',';
0354   }
0355   oss << ')';
0356   return oss.str();
0357 }