File indexing completed on 2025-01-30 09:17:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <DDRec/CellIDPositionConverter.h>
0015
0016 #include <DD4hep/Detector.h>
0017 #include <DD4hep/detail/VolumeManagerInterna.h>
0018
0019 #include <TGeoManager.h>
0020
0021 namespace dd4hep {
0022 namespace rec {
0023
0024 using std::set;
0025
0026 const VolumeManagerContext*
0027 CellIDPositionConverter::findContext(const CellID& cellID) const {
0028 return _volumeManager.lookupContext( cellID ) ;
0029 }
0030
0031
0032 Position CellIDPositionConverter::position(const CellID& cell) const {
0033
0034
0035
0036 return positionNominal( cell ) ;
0037 }
0038
0039 Position CellIDPositionConverter::positionNominal(const CellID& cell) const {
0040
0041 double l[3], e[3], g[3];
0042
0043 const VolumeManagerContext* context = findContext( cell ) ;
0044
0045 if( context == NULL)
0046 return Position() ;
0047
0048 DetElement det = context->element ;
0049
0050
0051 #if 0
0052
0053 PlacedVolume pv = context->placement ;
0054
0055 if( ! pv.volume().isSensitive() )
0056 return Position() ;
0057
0058 SensitiveDetector sd = pv.volume().sensitiveDetector();
0059 Readout r = sd.readout() ;
0060
0061 #else
0062
0063
0064
0065 Readout r = findReadout( det ) ;
0066
0067 #endif
0068
0069 Segmentation seg = r.segmentation() ;
0070 Position local = seg.position(cell);
0071
0072 local.GetCoordinates(l);
0073
0074 const TGeoMatrix& volToElement = context->toElement();
0075 volToElement.LocalToMaster(l, e);
0076
0077 const TGeoMatrix& elementToGlobal = det.nominal().worldTransformation();
0078 elementToGlobal.LocalToMaster(e, g);
0079
0080
0081 return Position(g[0], g[1], g[2]);
0082 }
0083
0084
0085
0086
0087 CellID CellIDPositionConverter::cellID(const Position& global) const {
0088
0089 CellID result(0) ;
0090
0091 TGeoManager *geoManager = _description->world().volume()->GetGeoManager() ;
0092
0093 PlacedVolume pv = geoManager->FindNode( global.x() , global.y() , global.z() ) ;
0094
0095 if( pv.isValid() && pv.volume().isSensitive() ) {
0096
0097 TGeoHMatrix* m = geoManager->GetCurrentMatrix() ;
0098
0099 double g[3], l[3] ;
0100 global.GetCoordinates( g ) ;
0101 m->MasterToLocal( g, l );
0102
0103 SensitiveDetector sd = pv.volume().sensitiveDetector();
0104 Readout r = sd.readout() ;
0105
0106
0107 PlacedVolume::VolIDs volIDs ;
0108 volIDs.insert( std::end(volIDs), std::begin(pv.volIDs()), std::end(pv.volIDs())) ;
0109
0110 TGeoPhysicalNode pN( geoManager->GetPath() ) ;
0111
0112 unsigned motherCount = 0 ;
0113
0114 while( pN.GetMother( motherCount ) != NULL ){
0115
0116 PlacedVolume mPv = pN.GetMother( motherCount++ ) ;
0117
0118 if( mPv.isValid() && pN.GetMother( motherCount ) != NULL )
0119 volIDs.insert( std::end(volIDs), std::begin(mPv.volIDs()), std::end(mPv.volIDs())) ;
0120 }
0121
0122 VolumeID volIDPVs = r.idSpec().encode( volIDs ) ;
0123
0124 result = r.segmentation().cellID( Position( l[0], l[1], l[2] ) , global, volIDPVs );
0125 }
0126
0127 return result ;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 namespace {
0191
0192 bool containsPoint( const DetElement& det, const Position& global ) {
0193
0194 if( det.volume().isValid() and det.volume().solid().isValid() ) {
0195
0196 double g[3], l[3] ;
0197 global.GetCoordinates( g ) ;
0198
0199 det.nominal().worldTransformation().MasterToLocal( g, l );
0200
0201 return det.volume().solid()->Contains( l ) ;
0202 }
0203
0204 return false ;
0205 }
0206
0207 }
0208
0209 DetElement CellIDPositionConverter::findDetElement(const Position& global,
0210 const DetElement& d) const {
0211
0212 DetElement det = ( d.isValid() ? d : _description->world() ) ;
0213
0214
0215
0216 if( containsPoint( det, global ) ) {
0217
0218 if( det.children().empty() )
0219 return det ;
0220
0221
0222
0223 DetElement result ;
0224 for( const auto& it : det.children() ){
0225
0226
0227
0228
0229 if( containsPoint( it.second , global ) ){
0230 result = it.second ;
0231 break ;
0232 }
0233 }
0234 if( result.isValid() ){
0235
0236 if( result.children().empty() )
0237 return result ;
0238 else
0239 return findDetElement( global, result ) ;
0240 }
0241
0242 }
0243
0244
0245 return DetElement() ;
0246 }
0247
0248 PlacedVolume CellIDPositionConverter::findPlacement(const Position& pos, const PlacedVolume& pv , double locPos[3], PlacedVolume::VolIDs& volIDs) const {
0249
0250
0251 double l[3] ;
0252 pos.GetCoordinates( l ) ;
0253
0254
0255
0256 if( pv.volume().solid()->Contains( l ) ) {
0257
0258
0259 volIDs.insert( std::end(volIDs), std::begin(pv.volIDs()), std::end(pv.volIDs()));
0260
0261 int ndau = pv->GetNdaughters() ;
0262
0263 if( ndau == 0 )
0264 return pv ;
0265
0266
0267
0268 PlacedVolume result ;
0269 for (int i = 0 ; i < ndau; ++i) {
0270
0271 PlacedVolume pvDau = pv->GetDaughter( i );
0272 pvDau->MasterToLocal( l , locPos ) ;
0273
0274
0275
0276
0277
0278
0279
0280
0281 if( pvDau.volume().solid()->Contains( locPos ) ) {
0282 result = pvDau ;
0283 volIDs.insert( std::end(volIDs), std::begin(pvDau.volIDs()), std::end(pvDau.volIDs()) );
0284 break ;
0285 }
0286 }
0287
0288 if( result.isValid() ){
0289
0290 if( result->GetNdaughters() == 0 ){
0291 return result ;
0292 } else
0293 return findPlacement( Position( locPos[0], locPos[1] , locPos[2] ), result , locPos , volIDs) ;
0294 }
0295
0296 }
0297
0298 return PlacedVolume() ;
0299 }
0300
0301
0302 Readout CellIDPositionConverter::findReadout(const DetElement& det) const {
0303
0304
0305 if (det.volume().isValid() and det.volume().isSensitive()) {
0306 SensitiveDetector sd = det.volume().sensitiveDetector();
0307 if (sd.isValid() and sd.readout().isValid()) {
0308 return sd.readout();
0309 }
0310 }
0311
0312
0313 Readout r = findReadout( det.placement() ) ;
0314 if( r.isValid() )
0315 return r ;
0316
0317
0318 return Readout();
0319 }
0320
0321 Readout CellIDPositionConverter::findReadout(const PlacedVolume& pv) const {
0322
0323
0324 if( pv.volume().isSensitive() ){
0325 SensitiveDetector sd = pv.volume().sensitiveDetector();
0326 if (sd.isValid() and sd.readout().isValid()) {
0327 return sd.readout();
0328 }
0329 }
0330
0331 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) {
0332
0333 PlacedVolume dpv = pv->GetDaughter(idau);
0334 Readout r = findReadout( dpv ) ;
0335 if( r.isValid() )
0336 return r ;
0337 }
0338
0339 return Readout() ;
0340 }
0341
0342 std::vector<double> CellIDPositionConverter::cellDimensions(const CellID& cell) const {
0343 auto context = findContext( cell ) ;
0344 if( context == nullptr ) return { };
0345 dd4hep::Readout r = findReadout( context->element ) ;
0346 dd4hep::Segmentation seg = r.segmentation() ;
0347 return seg.cellDimensions( cell );
0348 }
0349
0350
0351
0352
0353 }
0354 }