Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-14 22:36:08

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