Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-01-21 00:19:34

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     siliconAPVNum_ = getDouble("SiliconAPVNumber", *fv);
0100   }
0101 }
0102 
0103 /*
0104   Constructor from DD4hep Filtered view.
0105 */
0106 GeometricDet::GeometricDet(cms::DDFilteredView* fv, GeometricEnumType type)
0107     : ddname_(dd4hep::dd::noNamespace(fv->name())),
0108       type_(type),
0109       ddd_(fv->navPos()),  // To remove after DetExtra is removed (not used)
0110       trans_((fv->translation()) / dd4hep::mm),
0111       rho_(trans_.Rho()),
0112       phi_(trans_.Phi()),
0113       rot_(fv->rotation()),
0114       shape_(fv->shape()),
0115       params_(computeLegacyShapeParameters(shape_, fv->solid())),
0116       isFromDD4hep_(true) {
0117   using namespace angle_units::operators;
0118   if (almostEqual(phi_, -1._pi, 10)) {
0119     phi_ = 1._pi;
0120     // Standardize phi values of |pi| to be always +pi instead of sometimes -pi.
0121   }
0122 
0123   // Only look for sensor-related info on sensor volumes!
0124   if (type_ == DetUnit) {
0125     // IT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0126     pixROCRows_ = fv->get<double>("PixelROCRows");
0127     pixROCCols_ = fv->get<double>("PixelROCCols");
0128     pixROCx_ = fv->get<double>("PixelROC_X");
0129     pixROCy_ = fv->get<double>("PixelROC_Y");
0130 
0131     // Phase 1 OT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0132     stereo_ = (fv->get<std::string_view>("TrackerStereoDetectors") == strue);
0133     siliconAPVNum_ = fv->get<double>("SiliconAPVNumber");
0134 
0135     // Phase 2 OT sensors only (NB: hence could add a branch here, but not a critical part on perf)
0136     isLowerSensor_ = (fv->get<std::string_view>("TrackerLowerDetectors") == strue);
0137     isUpperSensor_ = (fv->get<std::string_view>("TrackerUpperDetectors") == strue);
0138 
0139     // All sensors: IT or OT, Phase 1 or Phase 2 (NB: critical part on perf)
0140     fv->findSpecPar("TrackerRadLength", "TrackerXi");
0141     radLength_ = fv->getNextValue("TrackerRadLength");
0142     xi_ = fv->getNextValue("TrackerXi");
0143   }
0144 }
0145 
0146 /*
0147   Constructor from persistent version (DB).
0148 */
0149 GeometricDet::GeometricDet(const PGeometricDet::Item& onePGD, GeometricEnumType type)
0150     : ddname_(onePGD._name),
0151       type_(type),
0152       ddd_(),
0153       geographicalID_(onePGD._geographicalID),
0154       trans_(onePGD._x, onePGD._y, onePGD._z),
0155       rho_(onePGD._rho),
0156       phi_(onePGD._phi),
0157       rot_(onePGD._a11,
0158            onePGD._a12,
0159            onePGD._a13,
0160            onePGD._a21,
0161            onePGD._a22,
0162            onePGD._a23,
0163            onePGD._a31,
0164            onePGD._a32,
0165            onePGD._a33),
0166       shape_(cms::dd::name_from_value(cms::LegacySolidShapeMap, static_cast<LegacySolidShape>(onePGD._shape))),
0167       params_(),
0168       radLength_(onePGD._radLength),
0169       xi_(onePGD._xi),
0170       pixROCRows_(onePGD._pixROCRows),
0171       pixROCCols_(onePGD._pixROCCols),
0172       pixROCx_(onePGD._pixROCx),
0173       pixROCy_(onePGD._pixROCy),
0174       stereo_(onePGD._stereo),
0175       siliconAPVNum_(onePGD._siliconAPVNum)
0176 // NB: what about new data members isLowerSensor_, isUpperSensor_, isFromDD4hep_?
0177 // They are presently not added to PGeometricDet (no change in info stored into DB).
0178 {
0179   // Solid shape parameters: only for box (1) and trapezoid (3)
0180   if (onePGD._shape == 1 || onePGD._shape == 3) {
0181     params_.reserve(11);
0182     params_.emplace_back(onePGD._params0);
0183     params_.emplace_back(onePGD._params1);
0184     params_.emplace_back(onePGD._params2);
0185     params_.emplace_back(onePGD._params3);
0186     params_.emplace_back(onePGD._params4);
0187     params_.emplace_back(onePGD._params5);
0188     params_.emplace_back(onePGD._params6);
0189     params_.emplace_back(onePGD._params7);
0190     params_.emplace_back(onePGD._params8);
0191     params_.emplace_back(onePGD._params9);
0192     params_.emplace_back(onePGD._params10);
0193   }
0194 
0195   ddd_.reserve(onePGD._numnt);
0196   ddd_.emplace_back(onePGD._nt0);
0197   ddd_.emplace_back(onePGD._nt1);
0198   ddd_.emplace_back(onePGD._nt2);
0199   ddd_.emplace_back(onePGD._nt3);
0200   if (onePGD._numnt > 4) {
0201     ddd_.emplace_back(onePGD._nt4);
0202     if (onePGD._numnt > 5) {
0203       ddd_.emplace_back(onePGD._nt5);
0204       if (onePGD._numnt > 6) {
0205         ddd_.emplace_back(onePGD._nt6);
0206         if (onePGD._numnt > 7) {
0207           ddd_.emplace_back(onePGD._nt7);
0208           if (onePGD._numnt > 8) {
0209             ddd_.emplace_back(onePGD._nt8);
0210             if (onePGD._numnt > 9) {
0211               ddd_.emplace_back(onePGD._nt9);
0212               if (onePGD._numnt > 10) {
0213                 ddd_.emplace_back(onePGD._nt10);
0214               }
0215             }
0216           }
0217         }
0218       }
0219     }
0220   }
0221 }
0222 
0223 std::unique_ptr<Bounds> GeometricDet::bounds() const {
0224   TrackerShapeToBounds shapeToBounds;
0225   return std::unique_ptr<Bounds>(shapeToBounds.buildBounds(shape_, params_));
0226 }
0227 
0228 GeometricDet::Position GeometricDet::positionBounds() const {
0229   Position pos_(static_cast<float>(geant_units::operators::convertMmToCm(trans_.x())),
0230                 static_cast<float>(geant_units::operators::convertMmToCm(trans_.y())),
0231                 static_cast<float>(geant_units::operators::convertMmToCm(trans_.z())));
0232   return pos_;
0233 }
0234 
0235 GeometricDet::Rotation GeometricDet::rotationBounds() const {
0236   Translation x, y, z;
0237   rot_.GetComponents(x, y, z);
0238   Rotation rotation_(float(x.X()),
0239                      float(x.Y()),
0240                      float(x.Z()),
0241                      float(y.X()),
0242                      float(y.Y()),
0243                      float(y.Z()),
0244                      float(z.X()),
0245                      float(z.Y()),
0246                      float(z.Z()));
0247   return rotation_;
0248 }
0249 
0250 GeometricDet::ConstGeometricDetContainer GeometricDet::deepComponents() const {
0251   // iterate on all the DESCENDANTS!!
0252   ConstGeometricDetContainer temp_;
0253   deepComponents(temp_);
0254   return temp_;
0255 }
0256 
0257 void GeometricDet::deepComponents(ConstGeometricDetContainer& cont) const {
0258   if (isLeaf())
0259     cont.emplace_back(this);
0260   else
0261     std::for_each(container_.begin(), container_.end(), [&](const GeometricDet* iDet) { iDet->deepComponents(cont); });
0262 }
0263 
0264 void GeometricDet::addComponents(GeometricDetContainer const& cont) {
0265   container_.reserve(container_.size() + cont.size());
0266   std::copy(cont.begin(), cont.end(), back_inserter(container_));
0267 }
0268 
0269 void GeometricDet::addComponents(ConstGeometricDetContainer const& cont) {
0270   container_.reserve(container_.size() + cont.size());
0271   std::copy(cont.begin(), cont.end(), back_inserter(container_));
0272 }
0273 
0274 void GeometricDet::addComponent(GeometricDet* det) { container_.emplace_back(det); }
0275 
0276 namespace {
0277   struct Deleter {
0278     void operator()(GeometricDet const* det) const { delete const_cast<GeometricDet*>(det); }
0279   };
0280 }  // namespace
0281 
0282 void GeometricDet::deleteComponents() {
0283   std::for_each(container_.begin(), container_.end(), Deleter());
0284   container_.clear();
0285 }
0286 
0287 /*
0288  * PRIVATE
0289  */
0290 
0291 /*
0292  * DD4hep.
0293  * Keep order and units of parameters same as old DD, to avoid numerous regressions.
0294  * Shape parameters of interest, and those to be stored in DB, are only from boxes, trapezoids, and tubs.
0295  * Hence, they are the only shapes treated here. 
0296  * params() will complain, if the parameters of any other shape are accessed.
0297  */
0298 std::vector<double> GeometricDet::computeLegacyShapeParameters(const cms::DDSolidShape& mySolidShape,
0299                                                                const dd4hep::Solid& mySolid) const {
0300   std::vector<double> myOldDDShapeParameters;
0301 
0302   // Box
0303   if (mySolidShape == cms::DDSolidShape::ddbox) {
0304     const dd4hep::Box& myBox = dd4hep::Box(mySolid);
0305     myOldDDShapeParameters = {(myBox.x()) / dd4hep::mm, (myBox.y()) / dd4hep::mm, (myBox.z()) / dd4hep::mm};
0306   }
0307 
0308   // Trapezoid
0309   else if (mySolidShape == cms::DDSolidShape::ddtrap) {
0310     const dd4hep::Trap& myTrap = dd4hep::Trap(mySolid);
0311     myOldDDShapeParameters = {(myTrap->GetDZ()) / dd4hep::mm,
0312                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetTheta())),
0313                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetPhi())),
0314                               (myTrap->GetH1()) / dd4hep::mm,
0315                               (myTrap->GetBl1()) / dd4hep::mm,
0316                               (myTrap->GetTl1()) / dd4hep::mm,
0317                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetAlpha1())),
0318                               (myTrap->GetH2()) / dd4hep::mm,
0319                               (myTrap->GetBl2()) / dd4hep::mm,
0320                               (myTrap->GetTl2()) / dd4hep::mm,
0321                               static_cast<double>(angle_units::operators::convertDegToRad(myTrap->GetAlpha2()))};
0322   }
0323 
0324   // Tub
0325   else if (mySolidShape == cms::DDSolidShape::ddtubs) {
0326     const dd4hep::Tube& myTube = dd4hep::Tube(mySolid);
0327     double phi1 = static_cast<double>(angle_units::operators::convertDegToRad(myTube->GetPhi1()));
0328     phi1 = cms_rounding::roundIfNear0(phi1);
0329     if (phi1 != 0.0) {
0330       using namespace angle0to2pi;
0331       phi1 = make0To2pi(phi1) - 2._pi;
0332       // Turn positive angle to negative
0333     }
0334     myOldDDShapeParameters = {
0335         (myTube->GetDz()) / dd4hep::mm,
0336         (myTube->GetRmin()) / dd4hep::mm,
0337         (myTube->GetRmax()) / dd4hep::mm,
0338         phi1,
0339         static_cast<double>(angle_units::operators::convertDegToRad(myTube->GetPhi2() - myTube->GetPhi1()))};
0340   }
0341 
0342   return myOldDDShapeParameters;
0343 }
0344 
0345 std::string GeometricDet::printNavType(int const* n, size_t sz) {
0346   std::ostringstream oss;
0347   oss << '(';
0348   for (int const* it = n; it != n + sz; ++it) {
0349     oss << *it << ',';
0350   }
0351   oss << ')';
0352   return oss.str();
0353 }