All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
SimDigitalGeom.cc
Go to the documentation of this file.
1 #include "SimDigitalGeom.h"
2 
3 #include "SimDigital.h"
4 
5 #include <marlin/Global.h>
6 #include <marlin/AIDAProcessor.h>
7 #include <AIDA/ITupleFactory.h>
8 #include <AIDA/ITuple.h>
9 
10 #include <DDSegmentation/BitField64.h>
11 #include <DDRec/CellIDPositionConverter.h>
12 #include <DD4hep/DetectorSelector.h>
13 
14 #include <limits>
15 
16 using namespace lcio ;
17 using namespace marlin ;
18 
19 
20 AIDA::ITuple* SimDigitalGeomCellId::_tupleHit = NULL;
21 AIDA::ITuple* SimDigitalGeomCellId::_tupleStep = NULL;
22 
23 void SimDigitalGeomCellId::bookTuples(const marlin::Processor* proc)
24 {
25  _tupleHit = AIDAProcessor::tupleFactory( proc )->create("SimDigitalGeom",
26  "SimDigital_Debug",
27  "int chtlayout,module,tower,stave,layer,I,J, float x,y,z, normalx,normaly,normalz, Ix,Iy,Iz,Jx,Jy,Jz");
28  streamlog_out(DEBUG) << "Tuple for Hit has been initialized to " << _tupleHit << std::endl;
29  streamlog_out(DEBUG)<< "it has " << _tupleHit->columns() << " columns" <<std::endl;
30 
31  _tupleStep = AIDAProcessor::tupleFactory( proc )->create("SimDigitalStep",
32  "SimDigital_DebugStep",
33  "int chtlayout,hitcellid,nstep, float hitx,hity,hitz,stepx,stepy,stepz,deltaI,deltaJ,deltaLayer,time");
34  streamlog_out(DEBUG) << "Tuple for Step has been initialized to " << _tupleStep << std::endl;
35  streamlog_out(DEBUG) << "it has " << _tupleStep->columns() << " columns" <<std::endl;
36 }
37 
38 
40  : _decoder(inputCol) , _encoder(inputCol->getParameters().getStringVal(LCIO::CellIDEncoding),outputCol) ,
41  _normal() , _Iaxis() , _Jaxis()
42 {
43  outputCol->parameters().setValue(LCIO::CellIDEncoding,inputCol->getParameters().getStringVal(LCIO::CellIDEncoding)) ;
44  _cellIDEncodingString = inputCol->getParameters().getStringVal(LCIO::CellIDEncoding) ;
45 }
46 
48  : SimDigitalGeomCellId(inputCol , outputCol)
49  // theDetector()
50 {
51  streamlog_out( DEBUG ) << "we will use lcgeo!" << std::endl ;
52 }
53 
55  : SimDigitalGeomCellId(inputCol , outputCol)
56  // theDetector()
57 {
58  streamlog_out( DEBUG ) << "we will use proto!" << std::endl ;
59 
60  _normal.set(0,0,1) ;
61  _Iaxis.set(1,0,0) ;
62  _Jaxis.set(0,1,0) ;
63 
64  _currentHCALCollectionCaloLayout = CHT::endcap ;
65 }
66 
68 {
69 }
70 
72 {
73 }
74 
76 {
77 }
78 
79 void SimDigitalGeomCellId::createStepAndChargeVec(SimCalorimeterHit* hit , std::vector<StepAndCharge>& vec, bool link)
80 {
81  LCVector3D hitPos ;
82  if (NULL != _hitPosition)
83  hitPos.set(_hitPosition[0] , _hitPosition[1] , _hitPosition[2]) ;
84 
85  std::map< unsigned int , std::vector<StepAndCharge> > stepMap ;
86 
87  if ( hit->getNMCContributions() == 0 )
88  return ;
89 
90  float currentTime = hit->getTimeCont(0) ;
91  PotentialSameTrackID id(hit->getPDGCont(0) , hit->getParticleCont(0)->getPDG() ) ;
92  unsigned int currentNum = 0 ;
93 
94  for (int imcp = 0 ; imcp < hit->getNMCContributions() ; imcp++)
95  {
96  LCVector3D stepPos ;
97  const float* pos = hit->getStepPosition(imcp) ;
98  if (NULL != pos)
99  {
100  stepPos.set(pos[0],pos[1],pos[2]) ;
101  stepPos -= hitPos ;
102  stepPos = LCVector3D(stepPos*_Iaxis,stepPos*_Jaxis,stepPos*_normal) ;
103 
104  PotentialSameTrackID stepID(hit->getPDGCont(imcp) , hit->getParticleCont(imcp)->getPDG() ) ;
105 
106  if ( std::abs( stepPos.z() ) < std::numeric_limits<float>::epsilon() ) // step in cell center so I assume it is unique and do not have to be linked
107  {
108  vec.push_back( StepAndCharge( stepPos , hit->getLengthCont(imcp) , hit->getTimeCont(imcp)) ) ;
109  currentNum++ ;
110  }
111  else //put it on the list of steps to be linked
112  {
113  if ( hit->getTimeCont(imcp) >= currentTime && (stepID == id) )
114  stepMap[ currentNum ].push_back( StepAndCharge( stepPos , hit->getLengthCont(imcp) , hit->getTimeCont(imcp)) ) ;
115  else
116  {
117  currentNum++ ;
118  stepMap[ currentNum ].push_back( StepAndCharge( stepPos , hit->getLengthCont(imcp) , hit->getTimeCont(imcp)) ) ;
119  }
120  }
121 
122  currentTime = hit->getTimeCont(imcp) ;
123  id.PDGStep = hit->getPDGCont(imcp) ;
124  id.PDGParent = hit->getParticleCont(imcp)->getPDG() ;
125  }
126  else
127  streamlog_out(WARNING) << "DIGITISATION : STEP POSITION IS (0,0,0)" << std::endl;
128  }
129 
130  if ( link )
131  {
132  for ( auto& it : stepMap )
133  linkSteps(it.second) ;
134  }
135 
136  for ( const auto& it : stepMap )
137  for ( const auto& step : it.second )
138  vec.push_back( step ) ;
139 
140  if ( vec.empty() )
141  streamlog_out(MESSAGE) << "no Steps in hit" << std::endl ;
142 }
143 
144 void SimDigitalGeomCellId::linkSteps(std::vector<StepAndCharge>& vec)
145 {
146  if ( vec.size() < 2 )
147  return ;
148 
149  float time = std::numeric_limits<float>::max() ;
150  float totalLength = 0 ;
151  LCVector3D pos(0,0,0) ;
152 
153  for ( const auto& step : vec )
154  {
155  totalLength += step.stepLength ;
156  pos += step.step * step.stepLength ;
157  time = std::min( time , step.time ) ;
158  }
159  pos /= totalLength ;
160 
161  totalLength = static_cast<float>( (vec.front().step - vec.back().step).mag() + 0.5f*(vec.front().stepLength + vec.back().stepLength) ) ;
162 
163  vec.clear() ;
164  vec.push_back( StepAndCharge(pos , totalLength , time) ) ;
165 }
166 
167 
168 void SimDigitalGeomCellIdLCGEO::processGeometry(SimCalorimeterHit* hit)
169 {
170  _cellIDvalue = _decoder( hit ).getValue() ;
171 
172  _trueLayer = _decoder( hit )[_encodingString.at(0)] - 1 ;
173  _stave = _decoder( hit )[_encodingString.at(1)] ; // +1
174  _module = _decoder( hit )[_encodingString.at(2)] ;
175 
176  if( _encodingString.at(3).size() != 0)
177  _tower = _decoder( hit )[_encodingString.at(3)] ;
178 
179  _Iy = _decoder( hit )[_encodingString.at(4)] ;
180  try
181  {
182  _Jz = _decoder( hit )[_encodingString.at(5)] ;
183  }
184  catch (lcio::Exception &)
185  {
186  _encodingString.at(5) = "z" ;
187 
188  try
189  {
190  _Jz = _decoder( hit )[_encodingString.at(5)] ;
191  }
192  catch(lcio::Exception &)
193  {
194  _encodingString.at(5) = "y" ;
195  _Jz = _decoder( hit )[_encodingString.at(5)] ;
196  }
197  }
198 
199  // _slice = _decoder( hit )["slice"];
200  _hitPosition = hit->getPosition() ;
201  if(abs(_Iy)<1 && abs(_Iy)!=0.0)
202  streamlog_out(DEBUG) << "_Iy, _Jz:"<<_Iy <<" "<<_Jz<< std::endl;
203  //if(_module==0||_module==6) streamlog_out( DEBUG )<<"tower "<<_tower<<" layer "<<_trueLayer<<" stave "<<_stave<<" module "<<_module<<std::endl;
204  //<<" Iy " << _Iy <<" Jz "<<_Jz<<" hitPosition "<<_hitPosition<<std::endl
205  //<<" _hitPosition[0] "<<_hitPosition[0]<<" _hitPosition[1] "<<_hitPosition[1]<<" _hitPosition[2] "<<_hitPosition[2]<<std::endl;
206 
207 
208  dd4hep::Detector& ild = dd4hep::Detector::getInstance() ;
209  dd4hep::rec::CellIDPositionConverter idposConv( ild ) ;
210 
211  dd4hep::BitField64 idDecoder( _cellIDEncodingString ) ;
212 
213  dd4hep::long64 id0 = hit->getCellID0() ;
214  dd4hep::long64 id1 = hit->getCellID1() ;
215 
216  idDecoder.setValue( id0 , id1 ) ;
217 
218  dd4hep::long64 id = idDecoder.getValue() ;
219  dd4hep::Position pos_0 = idposConv.position( id ) ;
220 
221 #if 0
222  const float* hitPos = hit->getPosition();
223 
224  streamlog_out( DEBUG ) << "hit pos: " << hitPos[0] << " " << hitPos[1] << " " << hitPos[2] << std::endl;
225  streamlog_out( DEBUG ) << "cell pos: " << pos_0.X() << " " << pos_0.Y() << " " << pos_0.Z() << std::endl;
226 
227  streamlog_out( DEBUG ) << "layer: " << idDecoder[_encodingStrings[_encodingType][0]]
228  << ", stave: " << idDecoder[_encodingStrings[_encodingType][1]]
229  << ", module: " << idDecoder[_encodingStrings[_encodingType][2]]
230  << ", tower: " << idDecoder[_encodingStrings[_encodingType][3]]
231  << ", x: " << idDecoder[_encodingStrings[_encodingType][4]]
232  << ", y: " << idDecoder[_encodingStrings[_encodingType][5]] << std::endl;
233 #endif
234 
235  double const epsilon = 1.e-3;
236 
237  ///// for direction x
238  dd4hep::Position pos_i_plus_1;
239  dd4hep::Position dir_i;
240 
241  std::string xEncoding = _encodingString.at(4) ;
242  std::string yEncoding = _encodingString.at(5) ;
243 
244  idDecoder[ xEncoding ] = idDecoder[ xEncoding ] + 1 ;
245  pos_i_plus_1 = idposConv.position( idDecoder.getValue() ) ;
246 
247  dir_i = pos_i_plus_1 - pos_0 ;
248 
249  if(dir_i.R() < epsilon)
250  {
251  idDecoder[ xEncoding ] = idDecoder[ xEncoding ] - 2 ;
252  pos_i_plus_1 = idposConv.position( idDecoder.getValue() ) ;
253  dir_i = - ( pos_i_plus_1 - pos_0 ) ;
254  }
255 
256  // reset
257  idDecoder.setValue( id0 , id1 ) ;
258 
259  ////// for direction y
260  dd4hep::Position pos_j_plus_1;
261  dd4hep::Position dir_j;
262 
263  idDecoder[ yEncoding ] = idDecoder[ yEncoding ] + 1 ;
264  pos_j_plus_1 = idposConv.position( idDecoder.getValue() ) ;
265 
266  dir_j = pos_j_plus_1 - pos_0 ;
267 
268  if(dir_j.R() < epsilon)
269  {
270  idDecoder[ yEncoding ] = idDecoder[ yEncoding ] - 2 ;
271  pos_j_plus_1 = idposConv.position( idDecoder.getValue() ) ;
272  dir_j = - ( pos_j_plus_1 - pos_0 ) ;
273  }
274 
275  dd4hep::Position dir_layer = dir_i.Cross( dir_j ) ;
276 
277  dir_layer = - dir_layer.Unit();
278 
279  //streamlog_out( DEBUG ) << "layer dir: " << dir_layer.X() << " " << dir_layer.Y() << " " << dir_layer.Z() << std::endl;
280 
281  dir_i = dir_i.Unit();
282  dir_j = dir_j.Unit();
283 
284  _normal.set(dir_layer.X(), dir_layer.Y(), dir_layer.Z()) ;
285  _Iaxis.set(dir_i.X(), dir_i.Y(), dir_i.Z()) ;
286  _Jaxis.set(dir_j.X(), dir_j.Y(), dir_j.Z()) ;
287 }
288 
289 void SimDigitalGeomCellIdPROTO::processGeometry(SimCalorimeterHit* hit)
290 {
291  _cellIDvalue = _decoder( hit ).getValue() ;
292 
293  _trueLayer = _decoder( hit )[_encodingString.at(0)] ;
294  _Iy = _decoder( hit )[_encodingString.at(4)] ;
295  _Jz = _decoder( hit )[_encodingString.at(5)] ;
296 
297  _hitPosition = hit->getPosition() ;
298 }
299 
300 std::vector<StepAndCharge> SimDigitalGeomCellId::decode(SimCalorimeterHit* hit , bool link)
301 {
302  this->processGeometry(hit) ;
303 
304  std::vector<StepAndCharge> stepsInIJZcoord ;
305 
306  this->createStepAndChargeVec(hit , stepsInIJZcoord , link) ;
307 
309  fillDebugTupleGeometryStep(hit , stepsInIJZcoord) ;
310 
311  return stepsInIJZcoord ;
312 }
313 
314 
316 {
317  //these tuples are for debugging geometry aspects
318  if (_tupleHit != nullptr)
319  {
321  _tupleHit->fill(TH_MODULE,_module);
322  _tupleHit->fill(TH_TOWER,_tower);
323  _tupleHit->fill(TH_STAVE,_stave);
325  _tupleHit->fill(TH_I,_Iy);
326  _tupleHit->fill(TH_J,_Jz);
327  if (_hitPosition != NULL)
328  {
329  _tupleHit->fill(TH_X,_hitPosition[0]); //x
330  _tupleHit->fill(TH_Y,_hitPosition[1]); //y
331  _tupleHit->fill(TH_Z,_hitPosition[2]); //z
332  }
333  else
334  {
335  float notset=-88888;
336  _tupleHit->fill(TH_X,notset);
337  _tupleHit->fill(TH_Y,notset);
338  _tupleHit->fill(TH_Z,notset);
339  }
340  for (int i=0; i<3; i++)
341  {
342  _tupleHit->fill(TH_NORMALX+i,_normal[i]);
343  _tupleHit->fill(TH_IX+i,_Iaxis[i]);
344  _tupleHit->fill(TH_JX+i,_Jaxis[i]);
345  }
346  _tupleHit->addRow() ;
347  }
348 }
349 
350 void SimDigitalGeomCellId::fillDebugTupleGeometryStep(SimCalorimeterHit* hit , const std::vector<StepAndCharge>& stepsInIJZcoord)
351 {
352  if (_tupleStep != nullptr )
353  {
354  int nsteps = hit->getNMCContributions() ;
355  float notset=-88888;
356  for (int imcp = 0 ; imcp<nsteps ; imcp++)
357  {
359  _tupleStep->fill(TS_HITCELLID,hit->getCellID0());
360  _tupleStep->fill(TS_NSTEP,nsteps);
361  const float* steppos = hit->getStepPosition(imcp) ;
362  for (int i=0; i<3; i++)
363  {
364  if (_hitPosition != NULL )
365  _tupleStep->fill(TS_HITX+i,_hitPosition[i]);
366  else
367  _tupleStep->fill(TS_HITX+i,notset);
368 
369 
370  if (steppos != NULL)
371  _tupleStep->fill(TS_STEPX+i,steppos[i]);
372  else
373  _tupleStep->fill(TS_STEPX+i,notset);
374 
375 
376  if (imcp < (int)stepsInIJZcoord.size() )
377  _tupleStep->fill(TS_DELTAI+i,stepsInIJZcoord[imcp].step[i]);
378  else
379  _tupleStep->fill(TS_DELTAI+i,notset);
380  }
381  if (imcp < (int)stepsInIJZcoord.size() )
382  _tupleStep->fill(TS_TIME,hit->getTimeCont(imcp)) ;
383  else
384  _tupleStep->fill(TS_TIME,notset) ;
385 
386  _tupleStep->addRow() ;
387  }
388  }
389 }
390 
391 
392 std::unique_ptr<CalorimeterHitImpl> SimDigitalGeomCellIdLCGEO::encode(int delta_I, int delta_J)
393 {
394  _encoder.setValue(_cellIDvalue) ;
395 
396  int RealIy = _Iy + delta_I ;
397  int RealJz = _Jz + delta_J ;
398 
399  _encoder[_encodingString.at(4)] = RealIy ;
400  _encoder[_encodingString.at(5)] = RealJz ;
401 
402  std::unique_ptr<CalorimeterHitImpl> hit( new CalorimeterHitImpl ) ;
403  _encoder.setCellID( hit.get() ) ;
404 
405  hit->setType( CHT( CHT::had, CHT::hcal , _currentHCALCollectionCaloLayout, _trueLayer ) );
406 
407  float posB[3] ;
408  posB[0] = static_cast<float>( _hitPosition[0] + getCellSize()*( delta_I*_Iaxis.x() + delta_J*_Jaxis.x() ) ) ;
409  posB[1] = static_cast<float>( _hitPosition[1] + getCellSize()*( delta_I*_Iaxis.y() + delta_J*_Jaxis.y() ) ) ;
410  posB[2] = static_cast<float>( _hitPosition[2] + getCellSize()*( delta_I*_Iaxis.z() + delta_J*_Jaxis.z() ) ) ;
411  hit->setPosition(posB) ;
412 
413  return hit ;
414 }
415 
416 std::unique_ptr<CalorimeterHitImpl> SimDigitalGeomCellIdPROTO::encode(int delta_I , int delta_J)
417 {
418  _encoder.setValue(_cellIDvalue) ;
419 
420  int RealIy = _Iy + delta_I ;
421  int RealJz = _Jz + delta_J ;
422 
423  if ( RealIy < 0 || RealJz < 0 )
424  return std::unique_ptr<CalorimeterHitImpl>(nullptr) ;
425 
426  _encoder[_encodingString.at(4)] = RealIy ;
427  _encoder[_encodingString.at(5)] = RealJz ;
428 
429  std::unique_ptr<CalorimeterHitImpl> hit( new CalorimeterHitImpl ) ;
430  _encoder.setCellID( hit.get() ) ;
431 
432  hit->setType( CHT( CHT::had, CHT::hcal , _currentHCALCollectionCaloLayout, _trueLayer ) );
433 
434  float posB[3] ;
435  posB[0] = static_cast<float>( _hitPosition[0] + getCellSize()*( delta_I*_Iaxis.x() + delta_J*_Jaxis.x() ) ) ;
436  posB[1] = static_cast<float>( _hitPosition[1] + getCellSize()*( delta_I*_Iaxis.y() + delta_J*_Jaxis.y() ) ) ;
437  posB[2] = static_cast<float>( _hitPosition[2] + getCellSize()*( delta_I*_Iaxis.z() + delta_J*_Jaxis.z() ) ) ;
438  hit->setPosition(posB) ;
439 
440  return hit ;
441 }
442 
444 {
446 
447  dd4hep::Detector & ild = dd4hep::Detector::getInstance() ;
448 
449  if(_currentHCALCollectionCaloLayout == CHT::barrel)
450  {
451  const std::vector< dd4hep::DetElement>& det = dd4hep::DetectorSelector(ild).detectors(
452  (dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL),
453  (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD) ) ;
454 
455  _caloData = det.at(0).extension<dd4hep::rec::LayeredCalorimeterData>();
456  //streamlog_out( DEBUG ) << "det size: " << det.size() << ", type: " << det.at(0).type() << endl;
457  }
458 
459  if(_currentHCALCollectionCaloLayout == CHT::ring)
460  {
461  const std::vector< dd4hep::DetElement>& det = dd4hep::DetectorSelector(ild).detectors(
462  (dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::AUXILIARY),
463  dd4hep::DetType::FORWARD) ;
464 
465  _caloData = det.at(0).extension<dd4hep::rec::LayeredCalorimeterData>();
466 
467  //streamlog_out( DEBUG ) << "det size: " << det.size() << ", type: " << det.at(0).type() << endl;
468  }
469 
470  if(_currentHCALCollectionCaloLayout == CHT::endcap)
471  {
472  const std::vector< dd4hep::DetElement>& det = dd4hep::DetectorSelector(ild).detectors(
473  (dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP),
474  (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD) ) ;
475 
476  _caloData = det.at(0).extension<dd4hep::rec::LayeredCalorimeterData>();
477  //streamlog_out( DEBUG ) << "det size: " << det.size() << ", type: " << det.at(0).type() << endl;
478  }
479 
480 }
481 
483 {
485 }
486 
488 {
489  float cellSize = 0.f ;
490  const double CM2MM = 10.0 ;
491 
492  if ( _cellSize > 0.0f )
493  return _cellSize ;
494 
495  if ( _caloData != nullptr )
496  {
497  const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer>& hcalBarrelLayers = _caloData->layers ;
498  cellSize = hcalBarrelLayers[_trueLayer].cellSize0 * CM2MM ;
499  }
500 
501  if ( cellSize < std::numeric_limits<float>::epsilon() )
502  streamlog_out( WARNING ) << "Cell Size is 0" << std::endl ;
503 
504  return cellSize ;
505 }
static void bookTuples(const marlin::Processor *proc)
virtual void processGeometry(SimCalorimeterHit *hit)
void fillDebugTupleGeometryStep(SimCalorimeterHit *hit, const std::vector< StepAndCharge > &stepsInIJZcoord)
virtual void processGeometry(SimCalorimeterHit *hit)
dd4hep::long64 _cellIDvalue
std::vector< std::string > _encodingString
SimDigitalGeomCellId(LCCollection *inputCol, LCCollectionVec *outputCol)
const float * _hitPosition
CellIDDecoder< SimCalorimeterHit > _decoder
std::vector< StepAndCharge > decode(SimCalorimeterHit *hit, bool link)
virtual float getCellSize()
static AIDA::ITuple * _tupleStep
void createStepAndChargeVec(SimCalorimeterHit *hit, std::vector< StepAndCharge > &vec, bool link)
virtual std::unique_ptr< CalorimeterHitImpl > encode(int delta_I, int delta_J)
virtual void processGeometry(SimCalorimeterHit *hit)=0
static AIDA::ITuple * _tupleHit
SimDigitalGeomCellIdLCGEO(LCCollection *inputCol, LCCollectionVec *outputCol)
virtual void setLayerLayout(CHT::Layout layout)
CellIDEncoder< CalorimeterHitImpl > _encoder
std::string _cellIDEncodingString
virtual std::unique_ptr< CalorimeterHitImpl > encode(int delta_I, int delta_J)
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
dd4hep::rec::LayeredCalorimeterData * _caloData
std::vector< std::string > _encodingString
virtual ~SimDigitalGeomCellId()
CHT::Layout _currentHCALCollectionCaloLayout
SimDigitalGeomCellIdPROTO(LCCollection *inputCol, LCCollectionVec *outputCol)
virtual void setLayerLayout(CHT::Layout layout)
void linkSteps(std::vector< StepAndCharge > &vec)