/// Compute the survey to-world transformation from the detector element placement with respect to the survey constants void DD4hep::Alignments::AlignmentTools::computeSurvey(Alignment alignment) { Alignment::Object* a = alignment.ptr(); DetElement parent = a->detector.parent(); MaskManipulator mask(a->flag); if ( parent.isValid() ) { DetectorTools::PlacementPath path; DetectorTools::placementPath(parent, a->detector, path); // TODO: need to take survey corrections into account! for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i) { const PlacedVolume& p = path[i]; a->detectorTrafo.MultiplyLeft(p->GetMatrix()); } a->worldTrafo = parent.survey()->worldTrafo; a->worldTrafo.MultiplyLeft(&a->detectorTrafo); a->trToWorld = Geometry::_transform(&a->worldTrafo); a->placement = a->detector.placement(); } mask.set(AlignmentData::SURVEY); //mask.clear(AlignmentData::INVALID|AlignmentData::DIRTY); //mask.set(AlignmentData::VALID|AlignmentData::IDEAL); }
// helper method to get the closest daughter DetElement to the position starting from the given DetElement DetElement IDDecoder::getClosestDaughter(const DetElement& det, const Position& position) { DetElement result; // check if we have a shape and see if we are inside if (det.volume().isValid() and det.volume().solid().isValid()) { double globalPosition[3] = { position.x(), position.y(), position.z() }; double localPosition[3] = { 0., 0., 0. }; det.worldTransformation().MasterToLocal(globalPosition, localPosition); if (det.volume().solid()->Contains(localPosition)) { result = det; } else { // assuming that any daughter shape would be inside this shape return DetElement(); } } const DetElement::Children& children = det.children(); DetElement::Children::const_iterator it = children.begin(); while (it != children.end()) { DetElement daughterDet = getClosestDaughter(it->second, position); if (daughterDet.isValid()) { result = daughterDet; break; } ++it; } return result; }
/* * Returns the closest detector element in the hierarchy for a given global position */ DetElement IDDecoder::detectorElement(const Position& pos) const { DetElement world = Geometry::LCDD::getInstance().world(); DetElement det = getClosestDaughter(world, pos); if (not det.isValid()) { throw invalid_position("DD4hep::DDRec::IDDecoder::detectorElement", pos); } std::cout << det.name() << std::endl; return det; }
/// Access mother volume by detector element Volume LCDDImp::pickMotherVolume(const DetElement& de) const { if ( de.isValid() ) { string de_name = de.name(); HandleMap::const_iterator i = m_motherVolumes.find(de_name); if (i == m_motherVolumes.end()) { return m_worldVol; } return (*i).second; } throw runtime_error("LCDD: Attempt access mother volume of invalid detector [Invalid-handle]"); }
/// Access optical surface data by its identifier OpticalSurface OpticalSurfaceManager::opticalSurface(DetElement de, const string& nam) const { if ( de.isValid() ) { Object* o = access(); string n = de.path() + '#' + nam; TGeoOpticalSurface* surf = o->detector.manager().GetOpticalSurface(n.c_str()); if ( surf ) return surf; auto i = o->opticalSurfaces.find(n); if ( i != o->opticalSurfaces.end() ) return (*i).second; return 0; } except("OpticalSurface", "++ Cannot access OpticalSurface %s without valid detector element!",nam.c_str()); return OpticalSurface(); }
int DeltaCollector<T>::operator()(DetElement de, int level) const { if ( de.isValid() ) { int count = 0; vector<Condition> conditions; cond::conditionsCollector(mapping,conditions)(de,level); for( auto cond : conditions ) { if ( cond->testFlag(Condition::ALIGNMENT_DELTA) ) { insert_item(deltas, de, cond.get<Delta>()); ++count; } } return count; } except("Alignments","Cannot process alignments of an invalid detector element"); return 0; }
/// Given a detector element, access it's sensitive detector (if the sub-detector is sensitive!) SensitiveDetector LCDDHelper::sensitiveDetector(DetElement detector) const { for(DetElement par = detector; par.isValid(); par = par.parent()) { if ( par.ptr() != ptr()->world().ptr() ) { PlacedVolume pv = par.placement(); if ( pv.isValid() ) { const PlacedVolume::VolIDs& ids = pv.volIDs(); for(PlacedVolume::VolIDs::const_iterator i=ids.begin(); i!=ids.end();++i) { if ( (*i).first == "system" ) { return sensitiveDetector(par.name()); } } } } } return SensitiveDetector(0); }
/// Compute the ideal/nominal to-world transformation from the detector element placement void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment) { Alignment::Object* a = alignment.ptr(); MaskManipulator mask(a->flag); DetElement parent = a->detector.parent(); if ( parent.isValid() ) { DetectorTools::PlacementPath path; DetectorTools::placementPath(parent, a->detector, path); for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i) { const PlacedVolume& p = path[i]; a->detectorTrafo.MultiplyLeft(p->GetMatrix()); a->nodes.push_back(p); } a->worldTrafo = parent.nominal()->worldTrafo; a->worldTrafo.MultiplyLeft(&a->detectorTrafo); a->trToWorld = Geometry::_transform(&a->worldTrafo); a->placement = a->detector.placement(); mask.clear(); mask.set(AlignmentData::HAVE_PARENT_TRAFO); mask.set(AlignmentData::HAVE_WORLD_TRAFO); mask.set(AlignmentData::IDEAL); } }