DD4hep  1.28.0
Detector Description Toolkit for High Energy Physics
CellIDPositionConverter.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : F.Gaede
11 //
12 //==========================================================================
13 
15 
16 #include "DD4hep/Detector.h"
18 
19 #include "TGeoManager.h"
20 
21 namespace dd4hep {
22  namespace rec {
23 
24  using std::set;
25 
26  const VolumeManagerContext*
29  }
30 
31 
33 
34  // untill we have the alignment map object, we return the nominal position
35 
36  return positionNominal( cell ) ;
37  }
38 
40 
41  double l[3], e[3], g[3];
42 
43  const VolumeManagerContext* context = findContext( cell ) ;
44 
45  if( context == NULL)
46  return Position() ;
47 
48  DetElement det = context->element ;
49 
50 
51 #if 0 // this uses the deprecated VolumeManagerContext::placement
52 
53  PlacedVolume pv = context->placement ;
54 
55  if( ! pv.volume().isSensitive() )
56  return Position() ;
57 
59  Readout r = sd.readout() ;
60 
61 #else
62 
63  // use a recursive search for the Readout
64 
65  Readout r = findReadout( det ) ;
66 
67 #endif
68 
69  Segmentation seg = r.segmentation() ;
70  Position local = seg.position(cell);
71 
72  local.GetCoordinates(l);
73 
74  const TGeoMatrix& volToElement = context->toElement();
75  volToElement.LocalToMaster(l, e);
76 
77  const TGeoMatrix& elementToGlobal = det.nominal().worldTransformation();
78  elementToGlobal.LocalToMaster(e, g);
79 
80 
81  return Position(g[0], g[1], g[2]);
82  }
83 
84 
85 
86 
88 
89  CellID result(0) ;
90 
91  TGeoManager *geoManager = _description->world().volume()->GetGeoManager() ;
92 
93  PlacedVolume pv = geoManager->FindNode( global.x() , global.y() , global.z() ) ;
94 
95  if( pv.isValid() && pv.volume().isSensitive() ) {
96 
97  TGeoHMatrix* m = geoManager->GetCurrentMatrix() ;
98 
99  double g[3], l[3] ;
100  global.GetCoordinates( g ) ;
101  m->MasterToLocal( g, l );
102 
104  Readout r = sd.readout() ;
105 
106  // collect all volIDs for the current path
107  PlacedVolume::VolIDs volIDs ;
108  volIDs.insert( std::end(volIDs), std::begin(pv.volIDs()), std::end(pv.volIDs())) ;
109 
110  TGeoPhysicalNode pN( geoManager->GetPath() ) ;
111 
112  unsigned motherCount = 0 ;
113 
114  while( pN.GetMother( motherCount ) != NULL ){
115 
116  PlacedVolume mPv = pN.GetMother( motherCount++ ) ;
117 
118  if( mPv.isValid() && pN.GetMother( motherCount ) != NULL ) // world has no volIDs
119  volIDs.insert( std::end(volIDs), std::begin(mPv.volIDs()), std::end(mPv.volIDs())) ;
120  }
121 
122  VolumeID volIDPVs = r.idSpec().encode( volIDs ) ;
123 
124  result = r.segmentation().cellID( Position( l[0], l[1], l[2] ) , global, volIDPVs );
125  }
126 
127  return result ;
128  }
129 
130  // CellID CellIDPositionConverter::cellID(const Position& global) const {
131 
132  // CellID result(0) ;
133 
134  // DetElement motherDet = _description->world() ; // could also start from an arbitrary DetElement here !?
135 
136  // DetElement det = findDetElement( global , motherDet ) ;
137 
138  // if( ! det.isValid() )
139  // return result ;
140 
141  // double g[3], e[3] , l[3] ;
142  // global.GetCoordinates( g ) ;
143  // det.nominal().worldTransformation().MasterToLocal( g, e );
144 
145  // PlacedVolume::VolIDs volIDs ;
146 
147  // PlacedVolume pv = findPlacement( Position( e[0], e[1] , e[2] ) , det.placement() , l , volIDs ) ;
148 
149  // TGeoManager *geoManager = det.volume()->GetGeoManager() ;
150  // // TGeoManager *geoManager = _description->world().volume()->GetGeoManager() ;
151 
152  // PlacedVolume pv1 = geoManager->FindNode( global.x() , global.y() , global.z() ) ;
153 
154  // // std::cout << " -> TGM : " << pv1.name() << " valid: " << pv1.isValid() << " sensitive: "
155  // // << (pv1.isValid() ? pv1.volume().isSensitive() : false ) << std::endl ;
156  // // std::cout << " -> FG : " << pv.name() << " valid: " << pv.isValid() << " sensitive: "
157  // // << (pv.isValid() ? pv.volume().isSensitive() : false ) << std::endl ;
158 
159 
160 
161  // if( pv.isValid() && pv.volume().isSensitive() ) {
162 
163  // SensitiveDetector sd = pv.volume().sensitiveDetector();
164  // Readout r = sd.readout() ;
165 
166  // VolumeID volIDElement = det.volumeID() ;
167  // // add the placed volumes volIDs:
168  // VolumeID volIDPVs = r.idSpec().encode( volIDs ) ;
169 
170  // result = r.segmentation().cellID( Position( l[0], l[1], l[2] ) , global, ( volIDElement | volIDPVs ) );
171 
172  // // } else {
173  // // std::cout << " *** ERROR : found no sensitive Placement " << pv.name()
174  // // << " for point " << global << " try with TGeoManager ... " << std::endl ;
175 
176  // // TGeoManager *geoManager = det.volume()->GetGeoManager() ;
177  // // // TGeoManager *geoManager = _description->world().volume()->GetGeoManager() ;
178 
179  // // PlacedVolume p = geoManager->FindNode( global.x() , global.y() , global.z() ) ;
180 
181  // // std::cout << " -> found: " << p.name() << " valid: " << p.isValid() << " sensitive: "
182  // // << (p.isValid() ? p.volume().isSensitive() : false ) << std::endl ;
183 
184  // }
185 
186  // return result ;
187  // }
188 
189 
190  namespace {
191 
192  bool containsPoint( const DetElement& det, const Position& global ) {
193 
194  if( det.volume().isValid() and det.volume().solid().isValid() ) {
195 
196  double g[3], l[3] ;
197  global.GetCoordinates( g ) ;
198 
199  det.nominal().worldTransformation().MasterToLocal( g, l );
200 
201  return det.volume().solid()->Contains( l ) ;
202  }
203 
204  return false ;
205  }
206 
207  }
208 
210  const DetElement& d) const {
211 
212  DetElement det = ( d.isValid() ? d : _description->world() ) ;
213 
214  // std::cout << " --- " << global << det.name() << std::endl ;
215 
216  if( containsPoint( det, global ) ) {
217 
218  if( det.children().empty() ) // no children -> we are done
219  return det ;
220 
221  // see if we have a child DetElement that contains the point ...
222 
223  DetElement result ;
224  for( auto it : det.children() ){
225  // std::cout << " - " << global << it.second.name() << " " << containsPoint( it.second , global )
226  // << " nChild: " << it.second.children().size() << " isValid: " << it.second.isValid()
227  // << std::endl ;
228 
229  if( containsPoint( it.second , global ) ){
230  result = it.second ;
231  break ;
232  }
233  }
234  if( result.isValid() ){ // ... yes, we have
235 
236  if( result.children().empty() ) // no more children -> done
237  return result ;
238  else
239  return findDetElement( global, result ) ; // keep searching in children
240  }
241 
242  }
243 
244  // point not contained
245  return DetElement() ;
246  }
247 
248  PlacedVolume CellIDPositionConverter::findPlacement(const Position& pos, const PlacedVolume& pv , double locPos[3], PlacedVolume::VolIDs& volIDs) const {
249 
250 
251  double l[3] ;
252  pos.GetCoordinates( l ) ;
253 
254  // std::cout << " --- " << pos << " " << pv.name() << " loc: (" << locPos[0] << "," << locPos[1] << "," << locPos[2] << ")" << std::endl ;
255 
256  if( pv.volume().solid()->Contains( l ) ) {
257 
258  // copy the volIDs
259  volIDs.insert( std::end(volIDs), std::begin(pv.volIDs()), std::end(pv.volIDs()));
260 
261  int ndau = pv->GetNdaughters() ;
262 
263  if( ndau == 0 ) // no daughter volumes -> we are done
264  return pv ;
265 
266  // see if we have a daughter volume that contains the point ...
267 
268  PlacedVolume result ;
269  for (int i = 0 ; i < ndau; ++i) {
270 
271  PlacedVolume pvDau = pv->GetDaughter( i );
272  pvDau->MasterToLocal( l , locPos ) ; // transform point to daughter's local frame
273 
274  // std::cout << " - " << pos << " " << pvDau.name()
275  // << " loc: (" << locPos[0] << "," << locPos[1] << "," << locPos[2] << ")"
276  // << pvDau.volume().solid()->Contains( locPos )
277  // << " ndau: " << pvDau->GetNdaughters()
278  // << std::endl ;
279 
280 
281  if( pvDau.volume().solid()->Contains( locPos ) ) { // point is contained in daughter node
282  result = pvDau ;
283  volIDs.insert( std::end(volIDs), std::begin(pvDau.volIDs()), std::end(pvDau.volIDs()) );
284  break ;
285  }
286  }
287 
288  if( result.isValid() ){ // ... yes, we have
289 
290  if( result->GetNdaughters() == 0 ){ // no more children -> done
291  return result ;
292  } else
293  return findPlacement( Position( locPos[0], locPos[1] , locPos[2] ), result , locPos , volIDs) ; // keep searching in daughter volumes
294  }
295 
296  }
297 
298  return PlacedVolume() ;
299  }
300 
301 
303 
304  // first check if top level is a sensitive detector
305  if (det.volume().isValid() and det.volume().isSensitive()) {
306  SensitiveDetector sd = det.volume().sensitiveDetector();
307  if (sd.isValid() and sd.readout().isValid()) {
308  return sd.readout();
309  }
310  }
311  // if not, return the first sensitive daughter volume's readout
312 
313  Readout r = findReadout( det.placement() ) ;
314  if( r.isValid() )
315  return r ;
316 
317  // nothing found !?
318  return Readout();
319  }
320 
322 
323  // first check if we are in a sensitive volume
324  if( pv.volume().isSensitive() ){
326  if (sd.isValid() and sd.readout().isValid()) {
327  return sd.readout();
328  }
329  }
330 
331  for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) {
332 
333  PlacedVolume dpv = pv->GetDaughter(idau);
334  Readout r = findReadout( dpv ) ;
335  if( r.isValid() )
336  return r ;
337  }
338 
339  return Readout() ;
340  }
341 
342  std::vector<double> CellIDPositionConverter::cellDimensions(const CellID& cell) const {
343  auto context = findContext( cell ) ;
344  if( context == nullptr ) return { };
345  dd4hep::Readout r = findReadout( context->element ) ;
347  return seg.cellDimensions( cell );
348  }
349 
350 
351 
352 
353  } /* namespace rec */
354 } /* namespace dd4hep */
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:206
dd4hep::rec::CellIDPositionConverter::findContext
const VolumeManagerContext * findContext(const CellID &cellID) const
Definition: CellIDPositionConverter.cpp:27
dd4hep::Detector::world
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
dd4hep::Segmentation::position
Position position(const CellID &cellID) const
determine the local position based on the cell ID
Definition: Segmentations.cpp:69
dd4hep::rec::CellIDPositionConverter::cellDimensions
std::vector< double > cellDimensions(const CellID &cell) const
Definition: CellIDPositionConverter.cpp:342
dd4hep::VolumeManager::lookupContext
VolumeManagerContext * lookupContext(VolumeID volume_id) const
Lookup the context, which belongs to a registered physical volume.
Definition: VolumeManager.cpp:605
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:44
Detector.h
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
VolumeManagerInterna.h
dd4hep::rec::CellIDPositionConverter::_volumeManager
VolumeManager _volumeManager
Definition: CellIDPositionConverter.h:120
dd4hep::VolumeManagerContext::element
DetElement element
Handle to the closest Detector element.
Definition: VolumeManager.h:53
dd4hep::rec::CellIDPositionConverter::findReadout
Readout findReadout(const DetElement &det) const
Definition: CellIDPositionConverter.cpp:302
dd4hep::rec::CellIDPositionConverter::positionNominal
Position positionNominal(const CellID &cellID) const
Definition: CellIDPositionConverter.cpp:39
dd4hep::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1223
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
dd4hep::rec::CellIDPositionConverter::cellID
CellID cellID(const Position &global) const
Definition: CellIDPositionConverter.cpp:87
dd4hep::Volume::isSensitive
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)
Definition: Volumes.cpp:1293
dd4hep::rec::CellIDPositionConverter::findPlacement
PlacedVolume findPlacement(const Position &point, const PlacedVolume &mother, double locPos[3], PlacedVolume::VolIDs &volIDs) const
Definition: CellIDPositionConverter.cpp:248
CellIDPositionConverter.h
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::PlacedVolumeExtension::VolIDs
Volume ID container.
Definition: Volumes.h:88
dd4hep::Segmentation::cellDimensions
std::vector< double > cellDimensions(const CellID &cellID) const
Returns a vector<double> of the cellDimensions of the given cell ID in natural order of dimensions,...
Definition: Segmentations.cpp:94
dd4hep::DetElement::volume
Volume volume() const
Access to the logical volume of the detector element's placement.
Definition: DetElement.cpp:351
dd4hep::IDDescriptor::encode
static VolumeID encode(const Field *fld, VolumeID value)
Encode partial volume identifiers to a volumeID.
Definition: IDDescriptor.cpp:148
dd4hep::rec::CellIDPositionConverter::findDetElement
DetElement findDetElement(const Position &global, const DetElement &det=DetElement()) const
Definition: CellIDPositionConverter.cpp:209
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::Segmentation::cellID
CellID cellID(const Position &localPosition, const Position &globalPosition, const VolumeID &volumeID) const
determine the cell ID based on the local position
Definition: Segmentations.cpp:74
dd4hep::VolumeManagerContext::toElement
const TGeoHMatrix & toElement() const
Access the transformation to the closest detector element.
Definition: VolumeManager.cpp:322
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:81
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::SensitiveDetector::readout
Readout readout() const
Access readout structure of the sensitive detector.
Definition: DetElement.cpp:419
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:452
dd4hep::PlacedVolumeExtension::VolIDs::insert
std::pair< std::vector< VolID >::iterator, bool > insert(const std::string &name, int value)
Insert new entry.
Definition: Volumes.cpp:406
dd4hep::VolumeManagerContext
This structure describes the cached data for one placement held by the volume manager.
Definition: VolumeManager.h:50
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::Segmentation
Handle class supporting generic Segmentations of sensitive detectors.
Definition: Segmentations.h:41
dd4hep::Readout::idSpec
IDDescriptor idSpec() const
Access IDDescription structure.
Definition: Readout.cpp:112
dd4hep::rec::CellIDPositionConverter::_description
const Detector * _description
Definition: CellIDPositionConverter.h:121
dd4hep::PlacedVolume::volIDs
const PlacedVolumeExtension::VolIDs & volIDs() const
Access to the volume IDs.
Definition: Volumes.cpp:480
dd4hep::rec::CellID
DDSegmentation::CellID CellID
Definition: CellIDPositionConverter.h:29
dd4hep::rec::CellIDPositionConverter::position
Position position(const CellID &cellID) const
Definition: CellIDPositionConverter.cpp:32
dd4hep::rec::VolumeID
DDSegmentation::VolumeID VolumeID
Definition: CellIDPositionConverter.h:30
dd4hep::Volume::sensitiveDetector
Handle< NamedObject > sensitiveDetector() const
Access to the handle to the sensitive detector.
Definition: Volumes.cpp:1287