Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-22 04:03:05

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