MarlinTrk  02.08
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MarlinDDKalTest.cc
Go to the documentation of this file.
3 
4 #include "kaltest/TKalDetCradle.h"
5 #include "kaltest/TVKalDetector.h"
6 #include "kaltest/THelicalTrack.h"
7 
8 #include "DDKalTest/DDVMeasLayer.h"
9 #include "DDKalTest/DDKalDetector.h"
10 #include "DDKalTest/DDCylinderMeasLayer.h"
11 
12 // #include "DDKalTest/DDSupportKalDetector.h"
13 // #include "DDKalTest/DDVXDKalDetector.h"
14 
15 //SJA:FIXME: only needed for storing the modules in the layers map
16 #include <UTIL/BitField64.h>
17 #include "UTIL/LCTrackerConf.h"
18 
19 #include "DDRec/SurfaceManager.h"
20 
21 #include <algorithm>
22 #include <string>
23 #include <math.h>
24 #include <cmath>
25 #include <fstream>
26 
27 #include <utility>
28 
29 #include "streamlog/streamlog.h"
30 
31 //#include "DDKalTest/DDMeasurementSurfaceStoreFiller.h"
32 
33 namespace MarlinTrk{
34 
35 
37  _ipLayer(NULL) {
38 
39  streamlog_out( DEBUG4 ) << " MarlinDDKalTest - initializing the detector ..." << std::endl ;
40 
41  _det = new TKalDetCradle ; // from kaltest. TKalDetCradle inherits from TObjArray ...
42  _det->SetOwner( true ) ; // takes care of deleting subdetector in the end ...
43 
44  is_initialised = false;
45 
46  this->registerOptions() ;
47 
48  streamlog_out( DEBUG4 ) << " MarlinDDKalTest - established " << std::endl ;
49  }
50 
52 
53 #ifdef MARLINTRK_DIAGNOSTICS_ON
54  _diagnostics.end();
55 #endif
56  for( auto* ddKalDet : _detectors ) { delete ddKalDet; }
57  delete _det ;
58  }
59 
60 
61  void MarlinDDKalTest::setOption(unsigned CFGOption, bool val) {
62 
63  IMarlinTrkSystem::setOption( CFGOption, val ) ;
64 
65  switch( CFGOption ) {
66 
68  this->includeMultipleScattering( val ) ;
69  break ;
71  this->includeEnergyLoss( val ) ;
72  break ;
73  // IMarlinTrkSystem::CFG::useSmoothing handled directly in MarlinDDKalTestTrack
74  }
75 
76  }
77 
78 
80 
81 
83 
85 
86  streamlog_out( DEBUG5 ) << " -------------------------------------------------------------------------------- " << std::endl ;
87  streamlog_out( DEBUG5 ) << " MarlinDDKalTest::init() called with the following options : " << std::endl ;
88  streamlog_out( DEBUG5 ) << this->getOptions() ;
89  streamlog_out( DEBUG5 ) << " -------------------------------------------------------------------------------- " << std::endl ;
90 
91  if( is_initialised ) {
92 
93  streamlog_out( DEBUG5 ) << " MarlinDDKalTest::init() - already initialized - only options are set .. " << std::endl ;
94 
95  return ;
96  }
97 
98 
99  streamlog_out( DEBUG5 ) << " ##################### MarlinDDKalTest::init() - initializing " << std::endl ;
100 
101  dd4hep::Detector& lcdd = dd4hep::Detector::getInstance();
102 
103  double minS = 1.e99;
104  DDCylinderMeasLayer* ipLayer = 0 ;
105 
106 
107  // for the tracking we get all tracking detectors and all passive detectors (beam pipe,...)
108 
109  std::vector< dd4hep::DetElement> detectors = lcdd.detectors( "tracker" ) ;
110  const std::vector< dd4hep::DetElement>& passiveDets = lcdd.detectors( "passive" ) ;
111  const std::vector< dd4hep::DetElement>& calos = lcdd.detectors( "calorimeter" ) ;
112 
113  detectors.reserve( detectors.size() + passiveDets.size() + calos.size() ) ;
114 
115  std::copy( passiveDets.begin() , passiveDets.end() , std::back_inserter( detectors ) ) ;
116 
117  for ( std::vector< dd4hep::DetElement>::const_iterator it=calos.begin() ; it != calos.end() ; ++it ){
118 
119  // for ( std::vector< dd4hep::DetElement>::const_iterator it=passiveDets.begin() ; it != passiveDets.end() ; ++it ){
120 
121  std::string name = it->name() ;
122  std::transform( name.begin() , name.end() , name.begin() , ::tolower ) ;
123  if( name.find( "ecal" ) != std::string::npos ){
124 
125  detectors.push_back( *it ) ;
126  }
127  }
128 
129 
130 
131  for ( std::vector< dd4hep::DetElement>::iterator it=detectors.begin() ; it != detectors.end() ; ++it ){
132 
133  dd4hep::DetElement det = *it ;
134 
135  streamlog_out( DEBUG5 ) << " MarlinDDKalTest::init() - creating DDKalDetector for : " << det.name() << std::endl ;
136 
137  _detectors.push_back( new DDKalDetector( det ) );
138  DDKalDetector* kalDet = _detectors.back();
139 
140  this->storeActiveMeasurementModuleIDs( kalDet ) ;
141 
142  _det->Install( *kalDet ) ;
143 
144 
145  Int_t nLayers = kalDet->GetEntriesFast() ;
146 
147 
148  // --- keep the cylinder meas layer with smallest sorting policy (radius) as ipLayer
149  // fixme: this should be implemented in a more explicit way ...
150  for( int i=0; i < nLayers; ++i ) {
151  const TVSurface* tvs = static_cast<const TVSurface*>( kalDet->At( i ) );
152 
153  double s = tvs->GetSortingPolicy() ;
154  if( s < minS && dynamic_cast< DDCylinderMeasLayer* > ( kalDet->At( i) ) ) {
155  minS = s ;
156  ipLayer = dynamic_cast< DDCylinderMeasLayer* > ( kalDet->At( i) ) ;
157  }
158  }
159 
160  if( streamlog_level( DEBUG5 ) ) { // dump surfaces to text file
161 
163  std::ofstream file ;
164  std::stringstream s ; s << "DDKalTest_" << det.name() << "_surfaces.txt" ;
165  file.open( s.str().c_str() , std::ofstream::out ) ;
166  lcio::BitField64 bf( UTIL::LCTrackerCellID::encoding_string() ) ;
167 
168  for( unsigned i=0,N=kalDet->GetEntriesFast() ; i<N ;++i){
169  DDVMeasLayer* ml = dynamic_cast<DDVMeasLayer*> ( kalDet->At( i ) ) ;
170  TVSurface* surf = dynamic_cast<TVSurface*> ( kalDet->At( i ) ) ;
171  smap[ surf->GetSortingPolicy() ] = ml ;
172  }
173  for( std::map<double,DDVMeasLayer*>::iterator itm=smap.begin() ; itm!=smap.end() ; ++itm){
174  bf.setValue( itm->second->getCellIDs()[0] ) ;
175  file << " " << std::scientific << std::setw(10) << itm->first << "\t" << bf.valueString() << *itm->second->surface() << "\n" ;
176  }
177  file.close() ;
178  }
179 
180  }
181 
182 
183 
184  if( ipLayer) {
185 
186  _ipLayer = ipLayer ;
187 
188  streamlog_out( MESSAGE ) << " MarlinDDKalTest: install IP layer at radius : " << minS << std::endl ;
189  }
190  //-------------------------------------------------------------------------------
191 
192 
193  _det->Close() ; // close the cradle
194  //done in Close() _det->Sort() ; // sort meas. layers from inside to outside
195 
196  streamlog_out( DEBUG4 ) << " MarlinDDKalTest - number of layers = " << _det->GetEntriesFast() << std::endl ;
197 
198 
199  if( streamlog_level( DEBUG ) ) {
200 
201  lcio::BitField64 bf( UTIL::LCTrackerCellID::encoding_string() ) ;
202 
203  for( unsigned i=0,N=_det->GetEntriesFast() ; i<N ;++i){
204 
205  DDVMeasLayer* ml = dynamic_cast<DDVMeasLayer*> ( _det->At( i ) ) ;
206 
207  bf.setValue( ml->getLayerID() ) ;
208 
209  TVSurface* s = dynamic_cast<TVSurface*> ( _det->At( i ) ) ;
210 
211  streamlog_out( DEBUG ) << " *** meas. layer : " << bf.valueString() << " sorting: " << s->GetSortingPolicy() << std::endl ;
212  }
213 
214  }
215 
216  is_initialised = true;
217 
218  }
219 
221 
222  if ( ! is_initialised ) {
223 
224  std::stringstream errorMsg;
225  errorMsg << "MarlinDDKalTest::createTrack: Fitter not initialised. MarlinDDKalTest::init() must be called before MarlinDDKalTest::createTrack()" << std::endl ;
226  throw MarlinTrk::Exception(errorMsg.str());
227 
228  }
229 
230  return new MarlinDDKalTestTrack(this) ;
231 
232  }
233 
235 
236  streamlog_out( DEBUG2 ) << " **** MarlinDDKalTest::includeMultipleScattering( " << msOn << " ) called " << std::endl ;
237 
238  if( msOn == true ) {
239  _det->SwitchOnMS();
240  }
241  else{
242  _det->SwitchOffMS();
243  }
244 
245  }
246 
247  void MarlinDDKalTest::includeEnergyLoss( bool energyLossOn ) {
248 
249  streamlog_out( DEBUG2 ) << " **** MarlinDDKalTest::includeEnergyLoss( " << energyLossOn << " ) called " << std::endl ;
250 
251  if( energyLossOn == true ) {
252  _det->SwitchOnDEDX();
253  }
254  else{
255  _det->SwitchOffDEDX();
256  }
257 
258  }
259 
261 
262  if( ! measmodules.empty() ) {
263 
264  std::stringstream errorMsg;
265  errorMsg << "MarlinDDKalTest::getSensitiveMeasurementModulesForLayer vector passed as second argument is not empty " << std::endl ;
266  throw MarlinTrk::Exception(errorMsg.str());
267 
268  }
269 
270  streamlog_out( DEBUG0 ) << "MarlinDDKalTest::getSensitiveMeasurementModulesForLayer: layerID = " << layerID << std::endl;
271 
272  std::multimap<Int_t, const DDVMeasLayer *>::const_iterator it; //Iterator to be used along with ii
273 
274 
275 
276  // for(it = _active_measurement_modules_by_layer.begin(); it != _active_measurement_modules_by_layer.end(); ++it) {
277  // streamlog_out( DEBUG0 ) << "Key = "<< ttdecodeILD(it->first) <<" Value = "<<it->second << std::endl ;
278  // }
279 
280 
282 
283  // set the module and sensor bit ranges to zero as these are not used in the map
284  lcio::BitField64 bf( UTIL::LCTrackerCellID::encoding_string() ) ;
285  bf.setValue( layerID ) ;
286  bf[lcio::LCTrackerCellID::module()] = 0 ;
287  bf[lcio::LCTrackerCellID::sensor()] = 0 ;
288  layerID = bf.lowWord();
289 
290  ii = this->_active_measurement_modules_by_layer.equal_range(layerID); // set the first and last entry in ii;
291 
292  for(it = ii.first; it != ii.second; ++it) {
293  // streamlog_out( DEBUG0 ) <<"Key = "<< it->first <<" Value = "<<it->second << std::endl ;
294  measmodules.push_back( it->second ) ;
295  }
296 
297  }
298 
300 
301  if( ! measmodules.empty() ) {
302 
303  std::stringstream errorMsg;
304  errorMsg << "MarlinDDKalTest::getSensitiveMeasurementLayer vector passed as second argument is not empty " << std::endl ;
305  throw MarlinTrk::Exception(errorMsg.str());
306 
307  }
308 
310  ii = this->_active_measurement_modules.equal_range(moduleID); // set the first and last entry in ii;
311 
312  std::multimap<int,const DDVMeasLayer *>::const_iterator it; //Iterator to be used along with ii
313 
314 
315  for(it = ii.first; it != ii.second; ++it) {
316  // std::cout<<"Key = "<<it->first<<" Value = "<<it->second << std::endl ;
317  measmodules.push_back( it->second ) ;
318  }
319  }
320 
321 
322  void MarlinDDKalTest::storeActiveMeasurementModuleIDs(TVKalDetector* detector) {
323 
324  Int_t nLayers = detector->GetEntriesFast() ;
325 
326  for( int i=0; i < nLayers; ++i ) {
327 
328  const DDVMeasLayer* ml = dynamic_cast<const DDVMeasLayer*>( detector->At( i ) );
329 
330  if( ! ml ) {
331  std::stringstream errorMsg;
332  errorMsg << "MarlinDDKalTest::storeActiveMeasurementLayerIDs dynamic_cast to DDVMeasLayer* failed " << std::endl ;
333  throw MarlinTrk::Exception(errorMsg.str());
334  }
335 
336  if( ml->IsActive() ) {
337 
338  // then get all the sensitive element id's assosiated with this DDVMeasLayer and store them in the map
339  std::vector<int>::const_iterator it = ml->getCellIDs().begin();
340 
341  while ( it!=ml->getCellIDs().end() ) {
342 
343  int sensitive_element_id = *it;
344  this->_active_measurement_modules.insert(std::pair<int,const DDVMeasLayer*>( sensitive_element_id, ml ));
345  ++it;
346 
347  }
348 
349  int subdet_layer_id = ml->getLayerID() ;
350 
352 
353  streamlog_out(DEBUG0) << "MarlinDDKalTest::storeActiveMeasurementLayerIDs added active layer with "
354  << " LayerID = " << subdet_layer_id << " and DetElementIDs " ;
355 
356  for (it = ml->getCellIDs().begin(); it!=ml->getCellIDs().end(); ++it) {
357 
358  streamlog_out(DEBUG0) << " : " << *it ;
359 
360  }
361 
362  streamlog_out(DEBUG0) << std::endl;
363 
364 
365 
366 
367  }
368 
369  }
370 
371  }
372 
373  const DDVMeasLayer* MarlinDDKalTest::getLastMeasLayer(THelicalTrack const& hel, TVector3 const& point) const {
374 
375  THelicalTrack helix = hel;
376 
377  double deflection_to_point = 0 ;
378  helix.MoveTo( point, deflection_to_point , 0 , 0) ;
379 
380  bool isfwd = ((helix.GetKappa() > 0 && deflection_to_point < 0) || (helix.GetKappa() <= 0 && deflection_to_point > 0)) ? true : false;
381 
382  int mode = isfwd ? -1 : +1 ;
383 
384  // streamlog_out( DEBUG4 ) << " MarlinDDKalTest - getLastMeasLayer deflection to point = " << deflection_to_point << " kappa = " << helix.GetKappa() << " mode = " << mode << std::endl ;
385  // streamlog_out( DEBUG4 ) << " Point to move to:" << std::endl;
386  // point.Print();
387 
388  int nsufaces = _det->GetEntriesFast();
389 
390  const TVSurface* ml_retval = nullptr;
391  double min_deflection = DBL_MAX;
392 
393  for(int i=0; i<nsufaces; ++i) {
394 
395  double defection_angle = 0 ;
396  TVector3 crossing_point ;
397 
398  const TVSurface *sfp = static_cast<const TVSurface *>(_det->At(i)); // surface at destination
399 
400  int does_cross = sfp->CalcXingPointWith(helix, crossing_point, defection_angle, mode) ;
401 
402  if( does_cross ) {
403 
404  const double deflection = fabs( deflection_to_point - defection_angle ) ;
405 
406  if( deflection < min_deflection ) {
407 
408  // streamlog_out( DEBUG4 ) << " MarlinDDKalTest - crossing found for suface = " << ml.GetMLName()
409  // << std::endl
410  // << " min_deflection = " << min_deflection
411  // << " deflection = " << deflection
412  // << " deflection angle = " << defection_angle
413  // << std::endl
414  // << " x = " << crossing_point.X()
415  // << " y = " << crossing_point.Y()
416  // << " z = " << crossing_point.Z()
417  // << " r = " << crossing_point.Perp()
418  // << std::endl ;
419 
420  min_deflection = deflection ;
421  ml_retval = sfp;
422  }
423 
424  }
425 
426  }
427 
428  return dynamic_cast<const DDVMeasLayer *>(ml_retval);
429  }
430 
431  const DDVMeasLayer* MarlinDDKalTest::findMeasLayer( EVENT::TrackerHit * trkhit) const {
432 
433  const TVector3 hit_pos( trkhit->getPosition()[0], trkhit->getPosition()[1], trkhit->getPosition()[2]) ;
434 
435  return this->findMeasLayer( trkhit->getCellID0(), hit_pos ) ;
436 
437  }
438 
439  const DDVMeasLayer* MarlinDDKalTest::findMeasLayer( int detElementID, const TVector3& point) const {
440 
441  const DDVMeasLayer* ml = 0; // return value
442 
443  std::vector<const DDVMeasLayer*> meas_modules ;
444 
445  // search for the list of measurement layers associated with this CellID
446  this->getSensitiveMeasurementModules( detElementID, meas_modules ) ;
447 
448  if( meas_modules.size() == 0 ) { // no measurement layers found
449 
451  encoder.setValue(detElementID) ;
452 
453  std::stringstream errorMsg;
454  errorMsg << "MarlinDDKalTest::findMeasLayer module id unkown: moduleID = " << detElementID
455  << " [" << encoder.valueString() << "]" << std::endl ;
456  throw MarlinTrk::Exception(errorMsg.str());
457 
458  }
459  else if (meas_modules.size() == 1) { // one to one mapping
460 
461  ml = meas_modules[0] ;
462 
463  }
464  else { // layer has been split
465 
466  bool surf_found(false);
467 
468  // loop over the measurement layers associated with this CellID and find the correct one using the position of the hit
469  for( unsigned int i=0; i < meas_modules.size(); ++i) {
470 
471 
472 
473  const TVSurface* surf = 0;
474 
475  if( ! (surf = dynamic_cast<const TVSurface*> ( meas_modules[i] )) ) {
476  std::stringstream errorMsg;
477  errorMsg << "MarlinDDKalTest::findMeasLayer dynamic_cast failed for surface type: moduleID = " << detElementID << std::endl ;
478  throw MarlinTrk::Exception(errorMsg.str());
479  }
480 
481  bool hit_on_surface = surf->IsOnSurface(point);
482 
483  if( (!surf_found) && hit_on_surface ){
484 
485  ml = meas_modules[i] ;
486  surf_found = true ;
487 
488  }
489  else if( surf_found && hit_on_surface ) { // only one surface should be found, if not throw
490 
491  std::stringstream errorMsg;
492  errorMsg << "MarlinDDKalTest::findMeasLayer point found to be on two surfaces: moduleID = " << detElementID << std::endl ;
493  throw MarlinTrk::Exception(errorMsg.str());
494  }
495 
496  }
497  if( ! surf_found ){ // print out debug info
498  streamlog_out(DEBUG1) << "MarlinDDKalTest::findMeasLayer point not found to be on any surface matching moduleID = "
499  << detElementID
500  << ": x = " << point.x()
501  << " y = " << point.y()
502  << " z = " << point.z()
503  << std::endl ;
504  }
505  else{
506  streamlog_out(DEBUG1) << "MarlinDDKalTest::findMeasLayer point found to be on surface matching moduleID = "
507  << detElementID
508  << ": x = " << point.x()
509  << " y = " << point.y()
510  << " z = " << point.z()
511  << std::endl ;
512  }
513  }
514 
515  return ml ;
516 
517  }
518 
519 } // end of namespace MarlinTrk
MarlinTrk::IMarlinTrack * createTrack()
instantiate its implementation of the IMarlinTrack
void registerOptions()
Register the possible configuration options.
T empty(T...args)
T copy(T...args)
void storeActiveMeasurementModuleIDs(TVKalDetector *detector)
Store active measurement module IDs for a given TVKalDetector needed for navigation.
virtual const double * getPosition() const =0
T open(T...args)
virtual void setOption(unsigned CFGOption, bool val)
Sets the specified option ( one of the constants defined in IMarlinTrkSystem::CFG ) to the given valu...
static const unsigned usedEdx
Use multiple scattering in the track fits.
T endl(T...args)
std::multimap< int, const DDVMeasLayer * > _active_measurement_modules_by_layer
virtual void setOption(unsigned CFGOption, bool val)
Sets the specified option ( one of the constants defined in IMarlinTrkSystem::CFG ) to the given valu...
const DDVMeasLayer * getLastMeasLayer(THelicalTrack const &helix, TVector3 const &point) const
std::vector< DDKalDetector * > _detectors
virtual std::string name()
the name of the implementation
void getSensitiveMeasurementModulesForLayer(int layerID, std::vector< const DDVMeasLayer * > &measmodules) const
Store active measurement module IDs needed for navigation.
T end(T...args)
void init()
initialise track fitter system
std::string valueString() const
STL class.
T setw(T...args)
STL class.
T push_back(T...args)
STL class.
void getSensitiveMeasurementModules(int detElementID, std::vector< const DDVMeasLayer * > &measmodules) const
Store active measurement module IDs needed for navigation.
const DDCylinderMeasLayer * _ipLayer
std::multimap< int, const DDVMeasLayer * > _active_measurement_modules
MarlinDDKalTest()
Default c&#39;tor.
Interface for generic tracks in MarlinTrk.
Definition: IMarlinTrack.h:36
T close(T...args)
T str(T...args)
static const std::string & encoding_string()
bool getOption(unsigned CFGOption)
Return the option&#39;s current value - false if option not defined.
void setValue(lcio::long64 value)
virtual int getCellID0() const =0
const DDVMeasLayer * findMeasLayer(EVENT::TrackerHit *trkhit) const
T scientific(T...args)
STL class.
T insert(T...args)
T find(T...args)
T size(T...args)
std::string getOptions()
String with all configuration options and their current values.
STL class.
T begin(T...args)
T back_inserter(T...args)
T back(T...args)
void includeEnergyLoss(bool on)
take energy loss into account during the fit
T transform(T...args)
Exception thrown in IMarlinTrk namespace (implemetations of IMarlinTrkSystem and IMarlinTrack).
tuple det
T equal_range(T...args)
static const unsigned useQMS
Use multiple scattering in the track fits.
T reserve(T...args)
void includeMultipleScattering(bool on)
take multiple scattering into account during the fit