All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
SiStripDigi.cc
Go to the documentation of this file.
1 // History:
2 //- added possibility to digitize forward slanted sensors with non-uniform pitch in RPhi (along Z-axiz), Z. Drasal Jul 2009
3 //- implemented new parameter for cut on time to emulate the integration time, K. Prothmann Dec. 2009
4 //- added possibility to digitize floating strips (in RPhi or Z) too, Z. Drasal Feb 2010
5 //- added detailed landau fluctuations in Si based on Geant 4 G4UniversalFluctuation, Z. Drasal Apr 2010
6 //- created only 1 relation TrackerPuls <--> SimTrackerHit, removed relations TrackerPulse <--> MCParticle, MCParticle <--> SimTrackerHit, Z. Drasal May 2010
7 //- corrected charge units, Z. Drasal May 2010
8 
9 
10 // FIXME: ?? No guarda los clusters con carga negativa??
11 
12 #include "SiStripDigi.h"
13 
14 #include "SiStripGeomBuilder.h"
15 
16 #include <cstdlib>
17 #include <iomanip>
18 #include <math.h>
19 #include <time.h>
20 
21 // Include CLHEP header files
22 #include <CLHEP/Random/Randomize.h>
23 #include <CLHEP/Vector/ThreeVector.h>
24 
25 // Include Digi header files
26 #include "Colours.h"
27 #include "DigiCluster.h"
28 #include "PhysicalConstants.h"
29 #include "RombIntSolver.h"
30 
31 // Include LCIO header files
32 #include <lcio.h>
33 #include <IMPL/LCCollectionVec.h>
34 #include <IMPL/LCFlagImpl.h>
35 #include <IMPL/LCRelationImpl.h>
36 #include <IMPL/TrackerPulseImpl.h>
37 #include <UTIL/CellIDDecoder.h>
38 #include <UTIL/CellIDEncoder.h>
39 #include "UTIL/LCTrackerConf.h"
40 
41 // Include Marlin
42 #include <streamlog/streamlog.h>
43 
44 // Namespaces
45 using namespace CLHEP;
46 using namespace lcio;
47 using namespace marlin;
48 
49 namespace sistrip {
50 
51 //
52 // Instantiate this object
53 //
55 
56 
57 // enum for variable map
58 enum { ELOSSDIGI,
60 };
61 
62 
63 // PUBLIC METHODS
64 
65 //
66 // Constructor
67 //
68 SiStripDigi::SiStripDigi() : Processor("SiStripDigi")
69 {
70  // Processor description
71  _description = "SiStripDigi: Marlin processor intended for detailed digitization of silicon strip sensors";
72 
73  //
74  // Processor parameters
75 
76  // Define compulsory parameters
77  //NEW -----
78  registerProcessorParameter( "Subdetector",
79  "Subdetector to be digitised",
81  std::string("FTD") );
82 
83  registerProcessorParameter( "DeplVoltage",
84  "Depletion voltage of a silicon strip detector, set in volts",
85  _Vdepl,
86  float(60) );
87 
88  registerProcessorParameter( "BiasVoltage",
89  "Bias voltage set on a silicon strip detector, set in volts",
90  _Vbias,
91  float(150) );
92 
93  registerProcessorParameter( "Temperature",
94  "Temperature measured on a sensor, set in Kelvins",
95  _temp,
96  float(300) );
97 
98  registerProcessorParameter( "LandauFluct",
99  "Use internal Landau fluctuations (instead of Geant4)?",
100  _landauFluct,
101  bool(true));
102 
103  registerProcessorParameter( "LandauBetaGammaCut",
104  "Below this beta*gamma factor internal Landau fluctuations not used",
106  float(0.7));
107 
108  registerProcessorParameter( "ProductionThreshOnDeltaRays",
109  "Production threshold cut on delta electrons in keV (for Landau fluct.) - use the same as in Geant4 (80keV ~ 0.05 mm)",
111  double(80));
112 
113  registerProcessorParameter( "ElectronicEffects",
114  "Apply electronic effects?",
116  bool(true));
117 
118  registerProcessorParameter( "InterStripCapacitance",
119  "Interstrip capacitance, set in pF",
121  float(6.) );
122 
123  registerProcessorParameter( "BackplaneCapacitance",
124  "Backplane capacitance, set in pF",
126  float(0.) );
127 
128  registerProcessorParameter( "CouplingCapacitance",
129  "Coupling capacitance, set in pF",
130  _capCoupl,
131  float(120.) );
132 
133  registerProcessorParameter( "ElectronicsNoise",
134  "Noise added by the electronics, set in electrons",
135  _elNoise,
136  float(1000) );
137 
138  registerProcessorParameter( "FloatingStripsRPhi",
139  "Is every even strip floating in R-Phi?",
141  bool(false));
142 
143  registerProcessorParameter( "FloatingStripsZ",
144  "Is every even strip floating in Z?",
146  bool(false));
147 
148  registerProcessorParameter( "AbsoluteSpacePrecision",
149  "Absolute digitization space precision, set in microns",
150  _epsSpace,
151  float(20) );
152 
153  registerProcessorParameter( "RelativeAnglePrecision",
154  "Relative digitization precision when calculating tan(Lorentz angle)",
155  _epsAngle,
156  float(0.01) );
157 
158  registerProcessorParameter( "RelativeDriftTimePrecision",
159  "Relative digitization precision when calculating cluster drift time",
160  _epsTime,
161  float(0.01) );
162 
163  registerProcessorParameter( "InputCollectionName",
164  "Name of SimTrackerHit input collection",
165  _inColName,
166  std::string("FTDCollection") );
167 
168  registerProcessorParameter( "OutputCollectionName",
169  "Name of TrackerPulse output collection",
170  _outColName,
171  std::string("FTDDigits") );
172 
173  registerProcessorParameter( "RelCollectionNameTrkPlsToSimHit",
174  "Name of relation collection - TrkPulses to SimTrackerHit (if nonzero, created)",
176  std::string("FTDDigitsToSimHitsRel") );
177 
178  registerProcessorParameter( "IntegrationWindow",
179  "Use integration window?",
181  bool(false));
182 
183  registerProcessorParameter( "StartIntegration",
184  "Only Simulated hits after the StartIntegration time in ns will be digitized",
186  double(-10.0));
187 
188  registerProcessorParameter( "StopIntegration",
189  "Only Simulated hits before the StopIntegration time in ns will be digitized",
191  double(10.0));
192 
193  registerProcessorParameter( "pitchFront",
194  "Pitch of the front sensor family in the center of the sensors, set in um",
195  _pitchFront,
196  double(50.0));
197 
198  registerProcessorParameter( "pitchRear",
199  "Pitch of the rear sensor family in the center of the sensors, set in um",
200  _pitchRear,
201  double(50.0));
202 }
203 
204 //
205 // Method called at the beginning of data processing
206 //
208 {
209  // Initialize variables
210  _nRun = 0 ;
211  _nEvent = 0 ;
212 
213  _currentLayerID = 0;
214  _currentLadderID = 0;
215  _currentSensorID = 0;
216 
217  _sensorThick =-1.;
218 
219  // Set variables in appropriate physical units
220  _Vdepl *= V ;
221  _Vbias *= V ;
222 
223  _temp *= K ;
224  _elNoise *= e ;
225  _epsSpace *= um;
226 
228 
230  _stopIntegration *= ns;
231 
232  _pitchFront *= um;
233  _pitchRear *= um;
234 
235 
236  // Get geometry parameters from Gear xml file
239  // _geometry -> printGearParams(); FIXME
240 
241  // Initialize random generator (engine, mean, sigma)
242  _genGauss = new RandGauss(new RandEngine(SEED), 0., (double)_elNoise);
243 
244  // Print set parameters
246 
247  // CPU time start
248  _timeCPU = clock()*us;
249 
250  // Internal Landau fluctuations
251  if (_landauFluct)
252  {
254  }
255 
256  //
257  // ROOT variables
258  //
259 #ifdef ROOT_OUTPUT_LAND
260  _rootFile = new TFile("Digi_FTD.root","RECREATE");
261  _rootFile->cd("");
262 
263  _tree = new TTree("Digi","Digi info");
264 
265  std::map<int,std::string> names;
266 
267  // Variables to store
268  _variables[ELOSSDIGI] = 0.0;
269  names[ELOSSDIGI] = "ELossDigi";
270 
271  _variables[ELOSSG4] = 0.0;
272  names[ELOSSG4] = "ELossG4";
273 
274 
275  for(std::map<int,double>::iterator it = _variables.begin();
276  it != _variables.end(); ++it)
277  {
278  _tree->Branch(names[it->first].c_str(),&(it->second),
279  (names[it->first]+"/D").c_str());
280  }
281 #endif
282 
283 }
284 
285 //
286 // Method called for each run
287 //
288 void SiStripDigi::processRunHeader(LCRunHeader * run)
289 {
290  // Print run number
291  streamlog_out(MESSAGE3) << DGREEN
292  << " Processing run: "
293  << ENDCOLOR
294  << (run->getRunNumber())
295  << std::endl << std::endl;
296 
297  // Add info about this process to LCIO run header
298  run->parameters().setValue ( "[ProcessorName]" , name() );
299  run->parameters().setValue ( "["+name()+"_gearType]" , _geometry->getGearType());
300  // run->parameters().setValue ( "["+name()+"_inColName]" , _inColName );
301  // run->parameters().setValue ( "["+name()+"_outColName]", _outColName );
302 
303  _nRun++;
304 }
305 
306 //
307 // Method called for each event
308 //
309 void SiStripDigi::processEvent(LCEvent * event)
310 {
311  // Local error count variable
312  static int errors_occured = 0;
313 
314  // Get names of all collections saved in LCIO file
315  ConstStringVec * strVec = event->getCollectionNames();
316 
317  // Initialize number of found muon hits versus all hits - efficiency map, resp.
318  // dep. energy in each event
319 #ifdef ROOT_OUTPUT_LAND
320  for(std::map<int,double>::iterator it = _variables.begin();
321  it != _variables.end(); ++it)
322  {
323  it->second = 0.0;
324  }
325 #endif
326 
327  //
328  // Get SimTrackerHit collection
329  LCCollection * colOfSimHits = 0;
330 
331  // Print header info about collections (for 1. event) // FIXME: To be deleted
332  if (event->getEventNumber() == 0)
333  {
334  streamlog_out(MESSAGE3) << " "
335  << DUNDERL
336  << DBLUE
337  <<"LCCollection processed:"
338  << ENDCOLOR
339  << std::endl << std::endl;
340  }
341 
342  // Go through all collection names and save the one that is defined as an input
343  // collection
344  for(ConstStringVec::const_iterator colName = strVec->begin();
345  colName != strVec->end(); ++colName)
346  {
347  if (_inColName == (*colName))
348  {
349  // Collection must be of SimTrackerHit type
350  if ( (event->getCollection(*colName))->getTypeName() ==
351  LCIO::SIMTRACKERHIT )
352  {
353  // Save collection
354  colOfSimHits = event->getCollection(*colName);
355  // Print info
356  if (event->getEventNumber() == 0)
357  {
358  streamlog_out(MESSAGE3) << " " << *colName
359  << std::endl;
360  }
361  }
362  // Collection NOT of SimTrackerHit type
363  else
364  {
365  streamlog_out(ERROR) << "Required collection: "
366  <<_inColName
367  << " found, but NOT of SIMTRACKERHIT type!!!"
368  << std::endl;
369  exit(-1);
370  }
371  }
372  } // For - collection names
373 
374  // Input collection NOT found
375  if (colOfSimHits == 0)
376  {
377  streamlog_out(WARNING) << "Required collection: "
378  <<_inColName
379  << " not found!!!"
380  << std::endl;
381  }
382 
383  // Print info
384  if (event->getEventNumber() == 0)
385  {
386  streamlog_out(MESSAGE3) << std::endl;
387  }
388  //
389  // Print event number
390  // if ( ((event->getEventNumber()+1)%100 == 0) || ((event->getEventNumber()+1) == 1))
391  if( (event->getEventNumber()+1)%100 == 0 )
392  {
393  streamlog_out(MESSAGE3) << DYELLOW
394  << " Processing event: "
395  << ENDCOLOR
396  << std::setw(5)
397  << (event->getEventNumber()+1)
398  << std::endl << std::endl;
399  }
400 
401  //
402  // Process SimTrackerHit collection
403  if(colOfSimHits != 0)
404  {
405  // Sensor map of strips with total integrated charge
406  SensorStripMap sensorMap;
407 
408  // Set collection decoder
409  CellIDDecoder<SimTrackerHit> cellIDDec(colOfSimHits);
410  // Guarda la string encoder...??
411 
412  // Get number of SimTrackerHits in the collection
413  int nHits = colOfSimHits->getNumberOfElements();
414 
415 
416  // Process hits
417  for (int i=0; i<nHits; ++i)
418  {
419  //
420  // Copy the content of current simhit to a DigiHit
421  SimTrackerHit * simHit = dynamic_cast<SimTrackerHitImpl*>( colOfSimHits->getElementAt(i) );
422 
423 #ifndef ROOT_OUTPUT_LAND
424  // Cut on simHit creation time --> simulate integration time of a sensor (if option switched on))
425  if( (simHit != 0) && (_integrationWindow))
426  {
427  if(simHit->getTime()*ns < _startIntegration ||
428  simHit->getTime()*ns > _stopIntegration)
429  {
430  errors_occured++;
431  continue;
432  }
433  }
434 #endif
435  // Hit phys. info
436  double hitPos[3] = {*(simHit->getPosition()) * mm,
437  *(simHit->getPosition()+1) * mm, *(simHit->getPosition()+2) * mm};
438  float hitMom[3] = {*(simHit->getMomentum()) * GeV,
439  *(simHit->getMomentum()+1) * GeV, *(simHit->getMomentum()+2) * GeV};
440  float hitdEdx = simHit->getEDep() * GeV;
441  float hitTime = simHit->getTime() * ns;
442  float hitPath = simHit->getPathLength() * mm;
443 
444  // Hit geom. info
445  // Recall: codification in Mokka/G4:
446  // Layer: 1,...7
447  // Side: -1 +1
448  // Petal: 1...16
449  // Sensor: 1 2 3 4
450  //---- The notation used in this code:
451  // Layer: 0,...., 6 (Positive Z)
452  // 7,....,13 (Negative Z)
453  // Petal: 0,....,15
454  // Sensor: 1 2 3 4
455  std::map<std::string,int> cellIDmap = _geometry->decodeCellID(cellIDDec(simHit)); //decodeCellID0
456  const int hitLayerID = cellIDmap["layer"];
457  const int hitLadderID = cellIDmap["module"];
458  const int hitSensorID = cellIDmap["sensor"];
459  //FIXME: The pixel disks digitization must be done
460  // by some other package...
461  if( abs(_geometry->getLayerRealID(hitLayerID)) < 3 )
462  {
463  continue;
464  }
465  int hitCellID = cellIDDec(simHit).lowWord();
466 
467  // MC information
468  MCParticle * mcPart = simHit->getMCParticle();
469 
470  //
471  // Set information of currently digitized hit
472  SimTrackerDigiHit * simDigiHit = new SimTrackerDigiHit();
473 
474  simDigiHit->setPrePosition(hitPos, hitMom, hitPath);
475  simDigiHit->setPosPosition(hitPos, hitMom, hitPath);
476  simDigiHit->setMomentum(hitMom);
477  simDigiHit->setEDep(hitdEdx);
478  simDigiHit->setTime(hitTime);
479  simDigiHit->setPathLength(hitPath);
480  simDigiHit->setCellID0(hitCellID);
481  simDigiHit->setLayerID(hitLayerID);
482  simDigiHit->setLadderID(hitLadderID);
483  simDigiHit->setSensorID(hitSensorID);
484  simDigiHit->setMCParticle(mcPart);
485  simDigiHit->setSimTrackerHit(dynamic_cast<EVENT::SimTrackerHit*>(simHit));
486 
487  // Set current layer --> ladder --> sensor ID
488  _currentLayerID = hitLayerID;
489  _currentLadderID = hitLadderID;
490  _currentSensorID = hitSensorID;
491 
492  // Set actual sensor geometry
494  // Set magnetic field
496 
497  // Transform hit to local ref. system of a sensor
498  transformSimHit(simDigiHit);
499 
500  // Transform magnetic field to local ref. system of a sensor
503 
504  // Digitize the given hit and get sensor map of strips with total
505  // integrated charge and time when a particle crossed the sensor
506  digitize(simDigiHit, sensorMap);
507 
508  // Unset actual sensor parameters
509  _currentLayerID = 0;
510  _currentLadderID = 0;
511  _currentSensorID = 0;
512 
513  _magField.set(0., 0., 0.);
514 
515  // Clear memory
516  delete simDigiHit;
517  simDigiHit = 0;
518 
519  } // For - process hits
520 
521  // Add electronics effects
523  {
524  // Calculate crosstalk and add this effect
525  calcCrossTalk(sensorMap);
526  // Generate noise and add this effect
527  genNoise(sensorMap);
528  }
529  // Print final info
530  printStripsInfo("all effects included", sensorMap);
531 
532  // Strips Types to loop overt there
533  std::vector<StripType> stripTypesvect;
534  stripTypesvect.push_back(STRIPFRONT);
535  stripTypesvect.push_back(STRIPREAR);
536 
537 /*#ifdef ROOT_OUTPUT_LAND
538  for(SensorStripMap::iterator itSM = sensorMap.begin(); itSM != sensorMap.end();
539  ++itSM)
540  {
541  const int cellID = itSM->first;
542  std::map<std::string,int> bfM = _geometry->decodeCellID(cellID);
543  const int diskID=bfM["layer"];
544  const int petalID=bfM["module"];
545  const int sensorID=bfM["sensor"];
546  std::cout << "-|| cellID: " << cellID
547  << " (layer:" << diskID << ", petal:"<< petalID
548  << ", sensor:"<< sensorID << ")" << std::endl;
549  for(std::vector<StripType>::iterator stT = stripTypesvect.begin();
550  stT != stripTypesvect.end(); ++stT)
551  {
552  for(StripChargeMap::iterator itSC = itSM->second[*stT].begin();
553  itSC != itSM->second[*stT].end(); ++itSC)
554  {
555  const double ylocal =_geometry->getStripPosY(diskID,sensorID,itSC->first,0.0);
556  const CLHEP::Hep3Vector PosGlobal0 = _geometry->transformPointToGlobal(diskID,petalID,sensorID,CLHEP::Hep3Vector(0.00,ylocal,0.0));
557  const CLHEP::Hep3Vector unitV = _geometry->getStripUnitVector(diskID,sensorID,itSC->first);
558  const double alpha = fabs(acos(unitV.getZ()));
559  const double ylocalL = ylocal+tan(alpha)*_geometry->getSensorLength(diskID);
560 
561  const CLHEP::Hep3Vector PosGlobal1 = _geometry->transformPointToGlobal(diskID,petalID,sensorID,CLHEP::Hep3Vector(0.00,ylocalL,_geometry->getSensorLength(diskID)));
562  std::cout << " |-|- stripID: " << itSC->first
563  << " -- Position (at zlocal=0):" << PosGlobal0
564  << " (at z=L:" << PosGlobal1 << ")" << std::endl;
565  std::cout << " |--- Total integrated charge: " << itSC->second->getCharge()/fC
566  << " fC (" << itSC->second->getCharge() << ")" << std::endl;
567  std::cout << " |--- Time : " << itSC->second->getTime()
568  << std::endl;
569  std::cout << " |-|- Simulated hits " << std::endl;
570  SimTrackerHitMap hm = itSC->second->getSimHitMap();
571  for(SimTrackerHitMap::iterator it = hm.begin(); it != hm.end();
572  ++it)
573  {
574  std::cout << " |-- Position Global[mm] : "
575  << "(" << (it->first->getPosition()[0]*mm)/mm
576  << "," << (it->first->getPosition()[1]*mm)/mm
577  << "," << (it->first->getPosition()[2]*mm)/mm << ")" << std::endl;
578  std::cout << " |-- Energy deposited[keV]: "
579  << it->first->getEDep()/keV << " (w=" << it->second
580  << ")" << std::endl;
581  std::cout << " |-- Path Length[um] : "
582  << it->first->getPathLength()/um << std::endl;
583  std::cout << " |-- CellID0 : "
584  << it->first->getCellID0() << std::endl;
585  std::cout << " |---------------------------" << std::endl;
586  }
587  }
588  }
589  std::cout << std::endl;
590  }
591 #endif*/
592 
593  //
594  // Create new collection (TrackerPulses + relations) from obtained results
595  IMPL::LCCollectionVec * colOfTrkPulses = new IMPL::LCCollectionVec(LCIO::TRACKERPULSE);
596 
597 
598  IMPL::LCCollectionVec * colOfRelPlsToSim = NULL;
599 
600 
601  if(!_relColNamePlsToSim.empty())
602  {
603  colOfRelPlsToSim = new IMPL::LCCollectionVec(LCIO::LCRELATION);
604  }
605 
606  // Set collection flag - cellID 1 will be stored, relations will contain weights
607  LCFlagImpl flag1(0), flag2(0);
608 
609  flag1.setBit(LCIO::TRAWBIT_ID1);
610  flag2.setBit(LCIO::LCREL_WEIGHTED);
611 
612  colOfTrkPulses->setFlag(flag1.getFlag());
613  if (!_relColNamePlsToSim.empty())
614  {
615  colOfRelPlsToSim->setFlag(flag2.getFlag());
616  }
617 
618  // CODIFICATION --->FIXME: METHOD IN GEAR (Centralizing...)
619  CellIDEncoder<TrackerPulseImpl> cellEnc(
620  LCTrackerCellID::encoding_string()+",stripType:2,stripID:11",
621  colOfTrkPulses);
622 
623  // TrackerPulses
624  SensorStripMap::iterator iterSMap;
625  StripChargeMap::iterator iterChMap;
626 
627 
628  for(iterSMap=sensorMap.begin(); iterSMap!=sensorMap.end(); ++iterSMap)
629  {
630  int cellID = iterSMap->first;
631 
632  for(std::vector<StripType>::iterator stripTypeIt = stripTypesvect.begin();
633  stripTypeIt != stripTypesvect.end(); ++stripTypeIt)
634  {
635  StripType stripType = *stripTypeIt;
636  for(iterChMap=iterSMap->second[stripType].begin();
637  iterChMap!=iterSMap->second[stripType].end(); ++iterChMap)
638  {
639  int stripID = iterChMap->first;
640 
641  // Create new Tracker pulse (time in ns, charge in fC), if charge
642  // positive, otherwise will be cut-out in clustering anyway
643  if(iterChMap->second->getCharge() > 0.*fC)
644  {
645  TrackerPulseImpl * trkPulse = new TrackerPulseImpl();
646 
647  //Storing the cellID0 and cellID1
648  _geometry->updateCanonicalCellID(cellID,stripType,stripID,
649  &cellEnc);
650  cellEnc.setCellID(trkPulse);
651 
652  trkPulse->setTime(iterChMap->second->getTime()/ns);
653  trkPulse->setCharge(iterChMap->second->getCharge()/fC);
654  trkPulse->setTrackerData(0);
655 
656  // Create relation from Tracker pulse to SimTrackerHit
657  if(!_relColNamePlsToSim.empty())
658  {
659  const SimTrackerHitMap & simHitMap = iterChMap->second->getSimHitMap();
660  float weightSum = iterChMap->second->getSimHitWeightSum();
661 
662  for(SimTrackerHitMap::const_iterator iterSHM=simHitMap.begin();
663  iterSHM!=simHitMap.end(); ++iterSHM)
664  {
665  // Create LC relation
666  LCRelationImpl * relation = new LCRelationImpl;
667  SimTrackerHit * simHit = iterSHM->first;
668  float weight = 0.;
669 
670  // Set from TrkPulse to MCParticle
671  relation->setFrom(trkPulse);
672  relation->setTo(simHit);
673  // Set weight
674  if(weightSum != 0.)
675  {
676  weight = float(iterSHM->second)/weightSum;
677  }
678  else
679  {
680  weight = 0.;
681  }
682  relation->setWeight(weight);
683 
684  // Add
685  if(weight != 0.)
686  {
687  colOfRelPlsToSim->addElement(relation);
688  }
689  else
690  {
691  delete relation;
692  }
693  }
694  }
695  // Save the pulse to the collection
696  colOfTrkPulses->addElement(trkPulse);
697  }
698 //FIXME: que pinta esto aqui
699 /* short int layerID = 0;
700  short int ladderID = 0;
701  short int sensorID = 0;
702  _geometry->decodeCellID(layerID, ladderID, sensorID, cellID);*/
703 
704  // Release memory
705  delete iterChMap->second;
706  }
707 
708  } // For for strips type
709  // Release memory
710  delete [] iterSMap->second;
711  } // For */
712  //
713  // Save the collection (vector) of pulses + relations to MC
714  event->addCollection(colOfTrkPulses, _outColName);
715 
716  if(!_relColNamePlsToSim.empty())
717  {
718  event->addCollection(colOfRelPlsToSim, _relColNamePlsToSim);
719  }
720 
721  } // If (colOfSimHits != 0)
722  if(errors_occured != 0)
723  {
724  streamlog_out(DEBUG4) << "SimTrackerHit outside "
725  << errors_occured << " times outside of integration time of sensor"
726  << std::endl;
727  }
728  errors_occured = 0;
729 
730 #ifdef ROOT_OUTPUT_LAND
731  _tree->Fill();
732 #endif
733  _nEvent++;
734 }
735 
736 //
737 // Method called after each event to check the data processed
738 //
739 void SiStripDigi::check(LCEvent * event)
740 {
741 }
742 
743 //
744 // Method called after all data processing
745 //
747 {
748  // Release memory
749  delete _geometry;
750  _geometry = 0;
751 
752  // CPU time end
753  _timeCPU = clock()*us - _timeCPU;
754 
755  // Print message
756  streamlog_out(MESSAGE3) << std::endl
757  << " "
758  << "Time per event: "
759  << std::setiosflags(std::ios::fixed | std::ios::internal )
760  << std::setprecision(3)
761  << _timeCPU/_nEvent/ms
762  << " ms"
763  << std::endl
764  << std::setprecision(3)
765  << std::endl
766  << DGREEN
767  << " "
768  << "Processor succesfully finished!"
769  << ENDCOLOR
770  << std::endl;
771 
772  // Clean memory
773  if (_landauFluct) delete _fluctuate;
774 
775 #ifdef ROOT_OUTPUT_LAND
776 
777  // Close file
778  _rootFile->cd("");
779  _rootFile->Write();
780  _rootFile->Close();
781 
782  delete _rootFile;
783 
784 #endif
785 }
786 
787 
788 // MAIN DIGI METHOD
789 
790 //
791 // The main method digitizing given hit (input parameter: a pointer to
792 // SimTrackerDigiHit, output parameter: sensor map of strips with total
793 // integrated charge and time when particle crossed the sensor)
794 //
795 void SiStripDigi::digitize(const SimTrackerDigiHit * simDigiHit, SensorStripMap & sensorMap)
796 {
797  //
798  // Calculate electron, resp. hole, clusters from obtained hits & provide Landau fluctuations
799  //DigiClusterVec eClusterVec;
800  DigiClusterVec hClusterVec;
801 
802  //FIXME: Return the vector, not passing per reference
803  calcClusters(simDigiHit, hClusterVec );
804 
805  //
806  // Go through all e, resp. h, clusters, perform drift, diffusion and Lorentz shift
807  DigiClusterVec::iterator iterVec;
808 
809  // Cluster - total diffusion - sigma
810  double diffSigma = 0.;
811 
812  // Cluster - Lorentz shift
813  Hep3Vector shiftLorentz(0.,0.,0.);
814 
815  // Cluster - total drift time
816  double driftTime = 0.;
817 
818  // Cluster - charge collected by a strip
819  double chargeCollect = 0.;
820 
821  // Get the type of strip (sensors 1,2 or sensors 3,4)
822  int stripType = -1;
823  if( _currentSensorID == 1 || _currentSensorID == 2 )
824  {
825  stripType = STRIPFRONT;
826  }
827  else if(_currentSensorID == 3 || _currentSensorID == 4 )
828  {
829  stripType = STRIPREAR;
830  }
831  else
832  {
833  streamlog_out(ERROR) << "SiStripDigi::digitize - "
834  << " Incoherent sensor ID! ID = " << _currentSensorID
835  << " do not exist. " << std::endl;
836  exit(-1);
837  }
838 
839  // Hole clusters
840  for( iterVec=hClusterVec.begin(); iterVec!=hClusterVec.end(); ++iterVec )
841  {
842  DigiCluster * cluster = (*iterVec);
843 
844  // Calculate charge collected by a strip (using Shockley-Ramo theorem
845  // dQh = |qClusterH * x / d|)
846  //chargeCollect = cluster->getNCarriers() *
847  // (cluster->getPosX())/_sensorThick * fC; // Presume that Z strips
848  //collect only holes
849  chargeCollect = cluster->getNCarriers() * e;
850 
851  // Calculate drift time
852  driftTime = getHoleDriftTime(cluster->getPosX());
853  cluster->setDriftTime(driftTime);
854 
855  // Calculate mean diffusivity and then diffusion sigma
856  diffSigma = getHoleDiffusivity(cluster->getPosX()/2.);
857  diffSigma *= 2 * driftTime;
858  diffSigma = sqrt(diffSigma);
859 
860  // Calculate Lorentz shift + evaluate cluster new position, i.e. X = 0.
861  shiftLorentz = getHoleLorentzShift(cluster->getPosX());
862  cluster->set3Position( shiftLorentz +
863  Hep3Vector(0., cluster->getPosY(),cluster->getPosZ()) );
864 
865  //
866  // Add diffusion effect and save results as signals (IN Z)
867  //
868  int iMinStrip = _geometry->getStripID( cluster->getLayerID(),
869  cluster->getSensorID(),
870  (cluster->getPosY() - 3.*diffSigma), cluster->getPosZ() );
871  int iMaxStrip = _geometry->getStripID( cluster->getLayerID(),
872  cluster->getSensorID(),
873  (cluster->getPosY() + 3.*diffSigma), cluster->getPosZ() );
874  double sensorPitch = _geometry->getSensorPitch( _currentLayerID,
875  _currentSensorID, cluster->getPosZ());
876 
877  // The calculus for the strips must be done in the (rotated by the
878  // stereo angle) local frame
879  const double tanPhi = tan(_geometry->getLayerHalfPhi(_currentLayerID));
880  //const double stAngle = _geometry->getStereoAngle(_currentLayerID,_currentSensorID);
881  const CLHEP::Hep3Vector pointRot = _geometry->transformPointToRotatedLocal(
883  CLHEP::Hep3Vector(0.,cluster->getPosY(),cluster->getPosZ()) );
884  const double zRot = pointRot.getZ();
885  const double yorigenRot = (_geometry->getSensorLength(_currentLayerID)-zRot)*tanPhi;
886 
887  // Gauss distr. - primitive function: from A to B
888  double meanRot = pointRot.getY();
889 
890  // Gauss distr. - primitive function: from A to B
891  //double mean = cluster->getPosY(); //cluster->getPosZ();
892 
893 
894  double sigmaSqrt2 = diffSigma * sqrt(2.);
895  double primAtA = 0.5*( 1. + erf( ((yorigenRot+iMinStrip*sensorPitch) - meanRot)/sigmaSqrt2) );
896  double primAtB = 0.;
897 
898  // Sensor map of strips with total integrated charge and time when particle
899  // crossed the detector
900  SensorStripMap::iterator iterSMap;
901  StripChargeMap::iterator iterChMap;
902 
903  // Strip signal
904  Signal * signal = 0;
905 
906  // Calculate signal at each strip and save
907  for(int i=iMinStrip; i<=iMaxStrip; ++i)
908  {
909  // Charge collected by a strip i
910  double charge = 0.;
911 
912  // Gauss distr. - prim. function at B
913  primAtB = 0.5*( 1. + erf( ((yorigenRot+(i+1)*sensorPitch) - meanRot)/sigmaSqrt2) );
914 
915  // Integration result
916  charge = (primAtB - primAtA) * chargeCollect;
917 
918  // New integration starting point
919  primAtA = primAtB;
920 
921  // Find sensor with given ID
922  iterSMap = sensorMap.find(cluster->getCellID());
923 
924  // Sensor has already collected some charge
925  if(iterSMap != sensorMap.end())
926  {
927  // Find strip i in Z
928  iterChMap = iterSMap->second[stripType].find(i);
929 
930  // Strip i in Z has already collected some charge
931  if(iterChMap != iterSMap->second[stripType].end())
932  {
933  // Get signal at strip i
934  signal = iterChMap->second;
935 
936  // Update signal information (add current charge to
937  // the total)
938  signal->updateCharge(charge);
939 
940  // Update MC truth information
941  signal->updateSimHitMap(cluster->getSimTrackerHit(),
942  charge);
943 
944  }
945  // Strip i in Z hasn't collected any charge yet
946  else
947  {
948  // Create signal, i.e. total charge + time when
949  // particle crossed the detector, all corresponding
950  // to strip i
951  signal = new Signal(charge, cluster->getTime());
952 
953  // Save MC truth information
954  signal->updateSimHitMap(cluster->getSimTrackerHit(),
955  charge);
956 
957  // Save information about strip i in Z
958  iterSMap->second[stripType][i] = signal;
959 
960  }
961  }
962  // Sensor has not collected any charge yet
963  else
964  {
965  // Create map of strips with total collected charge
966  StripChargeMap * stripMap = new StripChargeMap[2];
967 
968  // Create signal, i.e. total charge + time when particle crossed the
969  //detector, all corresponding to strip i
970  signal = new Signal(charge, cluster->getTime());
971 
972  // Save MC truth information
973  signal->updateSimHitMap(cluster->getSimTrackerHit(), charge);
974 
975  // Save information about strip i in Z
976  stripMap[stripType][i] = signal;
977  sensorMap[cluster->getCellID()] = stripMap;
978  }
979  } // Calculate signal at each strip
980  // Release memory
981  delete cluster;
982  cluster = 0;
983  } // For holes
984 
985  hClusterVec.clear();
986 }
987 
988 // OTHER METHODS
989 
990 //
991 // Method that calculates e-h clusters from simulated hits (parameters: a pointer
992 // to SimTrackerDigiHit and two vectors of pointers to electron, resp. hole
993 // clusters (pairs) )
994 //
996  //DigiClusterVec & eClusterVec, DigiClusterVec & hClusterVec)
997 {
998  //DigiCluster * eCluster = 0;
999  DigiCluster * hCluster = 0;
1000 
1001  // Calculate the number of clusters (each cluster sits in the middle of a substep,
1002  // where the substep increases precision of a step and corresponds to space precision)
1003  int nClusters = 0;
1004  int nSubSteps = (hit->getStepSize())/_epsSpace;
1005 
1006  if( (((hit->getStepSize()) - nSubSteps*_epsSpace) >= (0.5 * _epsSpace)) ||
1007  ((hit->getStepSize()) < _epsSpace) )
1008  {
1009  nClusters = nSubSteps + 1;
1010  }
1011  else
1012  {
1013  nClusters = nSubSteps;
1014  }
1015 
1016  // Calculate cluster step
1017  Hep3Vector clusterStep = hit->get3Step()/(nClusters);
1018 
1019  // Calculate variables relevant for Landau fluctuations - info about MC particle
1020  MCParticle * mcPart = dynamic_cast<MCParticle *>(hit->getMCParticle());
1021  double partMomMag = double(hit->get3Momentum().mag());
1022  double partMass = 0.;
1023  double betaGamma = 0.;
1024  if( mcPart!=0 )
1025  {
1026  partMass = hit->getMCParticle()->getMass()*GeV;
1027  }
1028  if(mcPart!=0 && partMass!=0.)
1029  {
1030  betaGamma = partMomMag / partMass;
1031  }
1032 
1033  double clusterStepSize = clusterStep.mag();
1034 
1035 #ifdef ROOT_OUTPUT_LAND
1036 
1037  // Update info
1038  _variables[ELOSSG4] += hit->getEDep()/keV;
1039  //_rootDepEG4 += hit->getEDep();
1040 #endif
1041  // Decide if particle is low-energy --> Geant 4 Landau fluctuations used in
1042  //low energy regime
1043  bool lowEnergyPart = false;
1044 
1045  if(betaGamma<_landauBetaGammaCut)
1046  {
1047  lowEnergyPart = true;
1048  }
1049 
1050  // Create elec-clusters and hole-clusters
1051  for(int i = 0; i<nClusters; ++i)
1052  {
1053  // Landau fluctuated deposited energy
1054  double eLoss = 0.;
1055 
1056  // High energy regime --> use internal Landau fluctuation (if defined)
1057  if(_landauFluct && !lowEnergyPart && mcPart!=0)
1058  {
1059  eLoss = _fluctuate->SampleFluctuations(mcPart, clusterStepSize);
1060  }
1061  // Low energy regime --> use Geant4 info and distribute it uniformly
1062  else
1063  {
1064  eLoss = hit->getEDep()/nClusters;
1065  }
1066 
1067 #ifdef ROOT_OUTPUT_LAND
1068  // Update info
1069  _variables[ELOSSDIGI] += eLoss/keV;
1070  //_rootDepEDigi += eLoss;
1071 #endif
1072 
1073  // Electron clusters
1074  /*eCluster = new DigiCluster(-1, hit->getTime(), eLoss,
1075  hit->get3PrePosition() + (i+0.5)*clusterStep,
1076  hit->getLayerID() , hit->getLadderID(),
1077  hit->getSensorID() , hit->getCellID0(),
1078  hit->getMCParticle(), hit->getSimTrackerHit());
1079  eClusterVec.push_back(eCluster);*/
1080 
1081  // Hole clusters
1082  hCluster = new DigiCluster(+1, hit->getTime(), eLoss,
1083  hit->get3PrePosition() + (i+0.5)*clusterStep,
1084  hit->getLayerID() , hit->getLadderID(),
1085  hit->getSensorID() , hit->getCellID0(),
1086  hit->getMCParticle(), hit->getSimTrackerHit());
1087  hClusterVec.push_back(hCluster);
1088  }
1089  // Print detailed info about clusters
1090  //printClustersInfo("Electron clusters in local ref. system", eClusterVec);
1091  printClustersInfo("Hole clusters in local ref. system", hClusterVec);
1092  streamlog_out(MESSAGE2) << std::endl;
1093 }
1094 
1095 
1096 //
1097 // Method that calculates crosstalk effect, i.e. total charge redistribution
1098 // (input parameter: sensor map of strips with total integrated charge)
1099 //
1101 {
1102  // Calculate how much charge is collected by adjacent strips
1103  // If read-out pitch = geom. pitch
1104  static float capRatio = _capInterStrip/(_capInterStrip + _capBackPlane + _capCoupl);
1105  // If read-out pitch = 2x geom. pitch
1106  static float capFloatRatio = _capInterStrip/2./(_capInterStrip/2. + _capBackPlane + _capCoupl);
1107 
1108  // Iterators
1109  SensorStripMap::iterator iterSMap;
1110  StripChargeMap::iterator iterChMap;
1111 
1112  short int layerID = 0;
1113  short int ladderID = 0;
1114  short int sensorID = 0;
1115 
1116  Signal * signal = 0 ;
1117 
1118  // Strips types
1119  std::vector<StripType> stvec;
1120  stvec.push_back(STRIPFRONT);
1121  stvec.push_back(STRIPREAR);
1122 
1123  // Go through all sensors
1124  for(iterSMap=sensorMap.begin(); iterSMap!=sensorMap.end(); ++iterSMap)
1125  {
1126  // Find corresponding layerID
1127  std::map<std::string,int> bfMap = _geometry->decodeCellID(iterSMap->first);
1128  layerID = bfMap["layer"];
1129  ladderID= bfMap["module"];
1130  sensorID= bfMap["sensor"];
1131  //_geometry->decodeCellID(layerID, ladderID, sensorID, iterSMap->first);
1132 
1133  // Define strip map with recalculated signals
1134  StripChargeMap * stripMap = new StripChargeMap[2];
1135 
1136  // For all the strips types
1137  for(std::vector<StripType>::iterator itT = stvec.begin(); itT != stvec.end(); ++itT)
1138  {
1139  const StripType STRIP = *itT;
1140  // Read map of strips in R-Phi and save new results to recalculated strip map
1141  for(iterChMap=(iterSMap->second[STRIP]).begin();
1142  iterChMap!=(iterSMap->second[STRIP]).end(); ++iterChMap)
1143  {
1144  const int iStrip = iterChMap->first;
1145  int iStripLeft = iStrip - 1;
1146  int iStripRight = iStrip + 1;
1147  double Kf = 0.;
1148 
1149  // Calculate charge redistribution
1150  signal = iterChMap->second;
1151 
1152  const double chargeTotal = signal->getCharge();
1153 
1154  SimTrackerHitMap simHitMapLeft;
1155  SimTrackerHitMap simHitMapCentr;
1156  SimTrackerHitMap simHitMapRight;
1157 
1158  // Floating strip - capRatio = 0.5
1159  if((_floatStripsRPhi) && (iStrip%2==1))
1160  {
1161  Kf = 0.5;
1162  }
1163  // Read-out strip, adjacent floating - capRatio = capFloatRatio
1164  else if((_floatStripsRPhi) && (iStrip%2==0))
1165  {
1166  Kf = capFloatRatio;
1167 
1168  iStripLeft--;
1169  iStripRight--;
1170  }
1171  // All strips are read-out - capRatio = catRatio
1172  else
1173  {
1174  Kf = capRatio;
1175  }
1176 
1177  // Calculating charge redistribution
1178  const double chargeLeft = chargeTotal*Kf;
1179  const double chargeRight = chargeTotal*Kf;
1180  const double chargeCentr = chargeTotal - chargeLeft - chargeRight;
1181 
1182  // Reasigning weights to hits
1183  for(SimTrackerHitMap::const_iterator iterSHM=signal->getSimHitMap().begin();
1184  iterSHM!=signal->getSimHitMap().end(); ++iterSHM)
1185  {
1186  simHitMapLeft[iterSHM->first] = iterSHM->second * Kf;
1187  simHitMapCentr[iterSHM->first] = iterSHM->second * chargeCentr/chargeTotal;
1188  simHitMapRight[iterSHM->first] = iterSHM->second * Kf;
1189  }
1190 
1191  // Time
1192  const double time = signal->getTime();
1193  // Left neighbour (crosstalk cannot go to non-existing strips, i.e. stripID >=0 && stripID < NSTRIPS
1194  if( (iStripLeft)>=0 )
1195  {
1196  if(stripMap[STRIP].find(iStripLeft) != stripMap[STRIP].end())
1197  {
1198  stripMap[STRIP][iStripLeft]->updateCharge(chargeLeft);
1199  stripMap[STRIP][iStripLeft]->updateSimHitMap(simHitMapLeft);
1200  }
1201  else
1202  {
1203  stripMap[STRIP][iStripLeft] = new Signal(chargeLeft, time);
1204  stripMap[STRIP][iStripLeft]->updateSimHitMap(simHitMapLeft);
1205  }
1206  }
1207  // Central strip
1208  if (chargeCentr!=0)
1209  {
1210  if(stripMap[STRIP].find(iStrip) != stripMap[STRIP].end())
1211  {
1212  stripMap[STRIP][iStrip]->updateCharge(chargeCentr);
1213  stripMap[STRIP][iStrip]->updateSimHitMap(simHitMapCentr);
1214  }
1215  else
1216  {
1217  stripMap[STRIP][iStrip] = new Signal(chargeCentr, time);
1218  stripMap[STRIP][iStrip]->updateSimHitMap(simHitMapCentr);
1219  }
1220  }
1221 
1222  // Right neighbour (crosstalk cannot go to non-existing strips, i.e. stripID >=0 && stripID < NSTRIPS
1223  if( (iStripRight)<_geometry->getSensorNStrips(layerID,sensorID) )
1224  {
1225  if (stripMap[STRIP].find(iStripRight) != stripMap[STRIP].end())
1226  {
1227  stripMap[STRIP][iStripRight]->updateCharge(chargeRight);
1228  stripMap[STRIP][iStripRight]->updateSimHitMap(simHitMapRight);
1229  }
1230  else
1231  {
1232  stripMap[STRIP][iStripRight] = new Signal(chargeRight, time);
1233  stripMap[STRIP][iStripRight]->updateSimHitMap(simHitMapRight);
1234  }
1235  }
1236 
1237  // Release memory
1238  delete iterChMap->second;
1239  }
1240  }
1241 
1242  // Delete previous strip map
1243  delete [] iterSMap->second;
1244 
1245  // Save new results
1246  iterSMap->second = stripMap;
1247  } // For
1248 
1249 }
1250 
1251 //
1252 // Method generating random noise using Gaussian distribution (input parameter:
1253 // sensor map of strips with total integrated charge)
1254 //
1256 {
1257  // Add noise, only if set nonzero!
1258  if (_elNoise < 1e-4)
1259  {
1260  return;
1261  }
1262 
1263  // Strips type
1264  std::vector<StripType> stvec;
1265  stvec.push_back(STRIPFRONT);
1266  stvec.push_back(STRIPREAR);
1267 
1268  for(SensorStripMap::iterator iterSMap=sensorMap.begin();
1269  iterSMap!=sensorMap.end(); ++iterSMap)
1270  {
1271  for(std::vector<StripType>::iterator itType = stvec.begin();
1272  itType != stvec.end(); ++itType)
1273  {
1274  for(StripChargeMap::iterator iterChMap=iterSMap->second[(*itType)].begin();
1275  iterChMap!=iterSMap->second[(*itType)].end();
1276  ++iterChMap)
1277  {
1278  const double elNoise = _genGauss->fire();
1279 
1280  iterChMap->second->updateCharge(elNoise);
1281  }
1282  }
1283  }
1284 }
1285 
1286 
1287 //
1288 // Method transforming given SimTrackerHit into local ref. system of each sensor, where
1289 // the system is positioned such as x, y and z coordinates are always positive;
1290 // positive X corresponds to the side collecting holes and X = 0 corresponds to
1291 // the strip collection electrons (parameter: a vector of pointers to
1292 // SimTrackerDigiHits).
1293 //
1295 {
1296  // Print sensor info
1297  streamlog_out(MESSAGE2) << " * Layer "
1299  << "Ladder "
1300  << _currentLadderID << " "
1301  << "Sensor "
1302  << _currentSensorID << " "
1303  << std::fixed
1304  << std::setprecision(2)
1305  << std::endl << " Local B field: "
1306  << _magField/T << " T"
1307  << std::setprecision(0)
1308  << std::endl;
1309 
1310  _geometry -> printSensorParams(_currentLayerID);
1311 
1312  // Print detailed info about hits in global ref. system
1313  printHitInfo("Hit in global ref. system",simDigiHit);
1314 
1315  // Hit global preStep, resp. posStep, positiona and momentum
1316  Hep3Vector globPrePosition = simDigiHit->get3PrePosition();
1317  Hep3Vector globPosPosition = simDigiHit->get3PosPosition();
1318  Hep3Vector globMomentum = simDigiHit->get3Momentum();
1319  // Hit local preStep, resp. posStep, position and momentum
1320  streamlog_out(DEBUG4) << "-- PRE-STEP Point" << std::endl;
1321  Hep3Vector locPrePosition = _geometry->transformPointToLocal(_currentLayerID,
1322  _currentLadderID, _currentSensorID, globPrePosition);
1323  streamlog_out(DEBUG4) << "-- POST-STEP Point" << std::endl;
1324  Hep3Vector locPosPosition = _geometry->transformPointToLocal(_currentLayerID,
1325  _currentLadderID, _currentSensorID, globPosPosition);
1326 
1327  Hep3Vector locMomentum = _geometry->transformVecToLocal(_currentLayerID,
1328  _currentLadderID, _currentSensorID, globMomentum);
1329 
1330  //-- Checking coherence
1331  // Avoid preStep rounding errors, checking inside sensitive
1332  const bool isPreIn = _geometry->isPointInsideSensor(_currentLayerID,
1333  _currentLadderID,_currentSensorID,locPrePosition);
1334  if( ! isPreIn )
1335  {
1336  streamlog_out(ERROR) << "SiStripDigi::transformSimHit: "
1337  << "Pre-step Position out of Sensor!\n" << std::endl;
1338  exit(-1);
1339  }
1340  // Avoid posStep rounding errors, checking inside sensitive
1342  _currentSensorID, locPosPosition);
1343  if( ! isPosIn )
1344  {
1345  streamlog_out(ERROR) << "SiStripDigi::transformSimHit: "
1346  << "Post-step Position out of Sensor!\n" << std::endl;
1347  exit(-1);
1348  }
1349 
1350  // Save hit local preStep, resp. posStep, position and momentum
1351  simDigiHit->set3PrePosition( locPrePosition );
1352  simDigiHit->set3PosPosition( locPosPosition );
1353  simDigiHit->set3Momentum( locMomentum );
1354 
1355  // Print detailed info about hit in local ref. system
1356  printHitInfo("Hit in local ref. system",simDigiHit);
1357 }
1358 
1359 
1360 // GET METHODS
1361 
1362 //
1363 // Method returning electron diffusivity (parameters: position in cm)
1364 //
1366 {
1367  // Electron mobility
1368  double mobility = getElecMobility(pos);
1369 
1370  return ( (k * _temp)/ePlus * mobility );
1371 }
1372 
1373 //
1374 // Method returning hole diffusivity (parameters: position in cm)
1375 //
1377 {
1378  // Hole mobility
1379  double mobility = getHoleMobility(pos);
1380 
1381  return ( (k * _temp)/ePlus * mobility );
1382 }
1383 
1384 //
1385 // Method returning electron drift time (parameters: position in cm)
1386 //
1388 {
1389  // Set pointer to velocity function and create instance of IntSolver
1390  double (SiStripDigi::* pfce)(double) = &SiStripDigi::getElecInvVelocity;
1391  RombIntSolver<SiStripDigi> elecIntSolver(pfce, this, _epsTime);
1392 
1393  if (pos>_sensorThick)
1394  {
1395  streamlog_out(ERROR) << "Problem to calculate total drift time. "
1396  << "Electrons at position: "
1397  << pos << " are out of range!" << std::endl;
1398  exit(-1);
1399  }
1400 
1401  // Result (Be carefull about rounding errors)
1402  if((_sensorThick - pos) <= ROUNDEPS*um)
1403  {
1404  return 0.;
1405  }
1406  else
1407  {
1408  return (elecIntSolver.Integrate(pos, _sensorThick));
1409  }
1410 }
1411 
1412 //
1413 // Method returning hole drift time (parameters: position X in cm)
1414 //
1416 {
1417  // Set pointer to velocity function and create instance of IntSolver
1418  double (SiStripDigi::* pfce)(double) = &SiStripDigi::getHoleInvVelocity;
1419  RombIntSolver<SiStripDigi> holeIntSolver(pfce, this, _epsTime);
1420 
1421  if(pos < -ROUNDEPS*um )
1422  {
1423  streamlog_out(ERROR) << "Problem to calculate total drift time."
1424  << " Holes at position: " << std::setprecision(5)
1425  << pos << " are out of range!"
1426  << std::endl;
1427  exit(-1);
1428  }
1429 
1430  // Result (Be carefull about rounding errors)
1431  if((pos) <= ROUNDEPS*um)
1432  {
1433  return 0.;
1434  }
1435  else
1436  {
1437  return (holeIntSolver.Integrate(pos, 0.));
1438  }
1439 }
1440 
1441 //
1442 // Method returning electric intensity in V/cm (parameters: position X in cm)
1443 //
1444 double SiStripDigi::getEField(double pos)
1445 {
1446  // Si wafer thickness in cm (Added the rounding error)
1447  if(pos< -ROUNDEPS*um || pos > _sensorThick+ROUNDEPS*um)
1448  {
1449  streamlog_out(ERROR) << std::setprecision(3)
1450  << "Electric field at required position[um]: " << pos/um
1451  << " not defined!" << std::endl;
1452  exit(-1);
1453  }
1454 
1455  // Return electric intensity
1456  return ( -(_Vbias+_Vdepl)/_sensorThick + 2*pos/(_sensorThick*_sensorThick)*_Vdepl );
1457 }
1458 
1459 //
1460 // Method returning electron mobility in cm^2/V.s (parameters: position X in cm)
1461 //
1463 {
1464  // Electron parameters - maximum velocity, critical intenzity, beta factor
1465  static double vmElec = 1.53 * pow(_temp,-0.87) * 1.E9 * cm/s;
1466  static double EcElec = 1.01 * pow(_temp,+1.55) * V/cm;
1467  static double betaElec = 2.57 * pow(_temp,+0.66) * 1.E-2;
1468 
1469  // Absolute value of electric intenzity
1470  double E = getEField(pos); if (E < 0.) E = -E;
1471 
1472  // Return mobility
1473  return ( vmElec/EcElec * 1./(pow(1. + pow((E/EcElec),betaElec),(1./betaElec))) );
1474 }
1475 
1476 //
1477 // Method returning hole mobility in cm^2/V.s (parameters: position X in cm)
1478 //
1480 {
1481  // Hole parameters - maximum velocity, critical intenzity, beta factor
1482  static double vmHole = 1.62 * pow(_temp,-0.52) * 1.E8 * cm/s;
1483  static double EcHole = 1.24 * pow(_temp,+1.68) * V/cm;
1484  static double betaHole = 0.46 * pow(_temp,+0.17);
1485 
1486  // Absolute value of electric intenzity
1487  double E = getEField(pos);
1488  if (E < 0.)
1489  {
1490  E = -E;
1491  }
1492 
1493  // Return mobility
1494  return ( vmHole/EcHole * 1./(pow(1. + pow((E/EcHole),betaHole),(1./betaHole))) );
1495 }
1496 
1497 //
1498 // Method that calculates Lorentz angle for electrons (parameters: position X
1499 // in cm)
1500 //
1501 Hep3Vector SiStripDigi::getElecLorentzShift(double pos)
1502 {
1503  // Set pointer to mobility function and create static instance to IntSolver
1504  double (SiStripDigi::* pfce)(double) = &SiStripDigi::getElecMobility;
1505  RombIntSolver<SiStripDigi> elecIntSolver(pfce, this, _epsAngle);
1506 
1507  // Hall scattering factor for electrons
1508  static float rElec = 1.13 + 0.0008*(_temp - 273);
1509 
1510  // Si wafer thickness in cm
1511  if (pos >_sensorThick)
1512  {
1513  streamlog_out(ERROR)
1514  << "Problem to calculate Lorentz angle. Electrons at position: "
1515  << pos << " are out of range!" << std::endl;
1516  exit(-1);
1517  }
1518 
1519  // Final Lorentz shift for electrons (Be careful about rounding errors)
1520  Hep3Vector shiftLorentz(0.,0.,0.);
1521 
1522  if((_sensorThick - pos) >= ROUNDEPS*um)
1523  {
1524  double integral = elecIntSolver.Integrate(pos, _sensorThick);
1525 
1526  shiftLorentz.setY(integral * rElec * _magField.getZ() * -1.); //????
1527  shiftLorentz.setZ(integral * rElec * _magField.getY()); //????
1528 
1529  //std::cout << "Mag field: " << _magField/T << " Lorentz shift: " << shiftLorentz/(_sensorThick-pos) << " " << (_sensorThick-pos)/um << " " << shiftLorentz << std::endl;
1530  }
1531 
1532  return (shiftLorentz);
1533 }
1534 
1535 //
1536 // Method that calculates Lorentz angle for holes (parameters: position X in cm)
1537 //
1538 Hep3Vector SiStripDigi::getHoleLorentzShift(double pos)
1539 {
1540  // Set pointer to mobility function and create static instance to IntSolver
1541  double (SiStripDigi::* pfce)(double) = &SiStripDigi::getHoleMobility;
1542  RombIntSolver<SiStripDigi> holeIntSolver(pfce, this);
1543 
1544  // Hall scattering factor for holes
1545  static float rHole = 0.72 - 0.0005*(_temp - 273);
1546 
1547  // Si wafer thickness in cm
1548  if(pos < -ROUNDEPS*um)
1549  {
1550  streamlog_out(ERROR) << "Problem to calculate Lorentz angle."
1551  << " Holes at position: " << pos << " are out of range!"
1552  << std::endl;
1553  exit(-1);
1554  }
1555 
1556  // Final Lorentz shift for holes (Be careful about rounding errors)
1557  Hep3Vector shiftLorentz(0.,0.,0.);
1558  if(pos >= ROUNDEPS*um)
1559  {
1560  double integral = holeIntSolver.Integrate(0., pos);
1561 
1562  shiftLorentz.setY(integral * rHole * _magField.getZ()); //????
1563  shiftLorentz.setZ(integral * rHole * _magField.getY() * -1.); //????
1564  }
1565 
1566  return (shiftLorentz);
1567 }
1568 
1569 //
1570 // Method that returns actual electron velocity (parameters: position in cm)
1571 //
1573 {
1574  return (-1.*getElecMobility(pos)*getEField(pos));
1575 }
1576 
1577 //
1578 // Method that returns actual electron inverse velocity (parameters: position in cm)
1579 //
1581 {
1582  return ( -1./(getElecMobility(pos)*getEField(pos)) );
1583 }
1584 
1585 //
1586 // Method that returns actual hole velocity (parameters: position in cm)
1587 //
1589 {
1590  return (getHoleMobility(pos)*getEField(pos));
1591 }
1592 
1593 //
1594 // Method that returns actual hole inverse velocity (parameters: position in cm)
1595 //
1597 {
1598  return ( 1./(getHoleMobility(pos)*getEField(pos)) );
1599 }
1600 
1601 
1602 // PRINT METHODS
1603 
1604 //
1605 // Method printing cluster info
1606 //
1607 void SiStripDigi::printClusterInfo( const DigiCluster & cluster) const
1608 {
1609  streamlog_out(MESSAGE1) << std::setiosflags(std::ios::fixed | std::ios::internal | std::ios::showpos)
1610  << std::setprecision(2)
1611  << " Cluster:"
1612  << " Q [fC]: " << cluster.getNCarriers()*cluster.getCharge()/fC
1613  << std::setprecision(1)
1614  << " Pos X [um]: " << std::setw(6) << cluster.getPosX()/um
1615  << std::setprecision(3)
1616  << " Pos Y [mm]: " << std::setw(6) << cluster.getPosY()/mm
1617  << " Pos Z [mm]: " << std::setw(6) << cluster.getPosZ()/mm
1618  << std::resetiosflags(std::ios::internal | std::ios::showpos)
1619  << std::setprecision(0)
1620  << std::endl;
1621 }
1622 
1623 //
1624 // Method printing clusters info (clusters in std::vector)
1625 //
1626 void SiStripDigi::printClustersInfo( std::string info, const DigiClusterVec & clusterVec) const
1627 {
1628  DigiClusterVec::const_iterator iterClusters;
1629 
1630  streamlog_out(MESSAGE1) << " " << info << ": " << clusterVec.size() << " clusters" <<std::endl;
1631  for ( iterClusters = clusterVec.begin(); iterClusters != clusterVec.end(); ++iterClusters ) {
1632  printClusterInfo( **iterClusters);
1633  }
1634 }
1635 
1636 //
1637 // Method printing hit info
1638 //
1639 void SiStripDigi::printHitInfo( std::string info, const SimTrackerDigiHit * hit) const
1640 {
1641  streamlog_out(MESSAGE2) << " " << info << ":" << std::endl;
1642  streamlog_out(MESSAGE2) << std::fixed
1643  << std::setprecision(1)
1644  << " Hit:"
1645  << " DepE [keV]: " << hit->getEDep()/keV
1646  << std::setprecision(3)
1647  << std::setiosflags(std::ios::showpos)
1648  << " Pos X [mm]: " << (hit->getPreX() + hit->getPosX())/2./mm
1649  << " Pos Y [mm]: " << (hit->getPreY() + hit->getPosY())/2./mm
1650  << " Pos Z [mm]: " << (hit->getPreZ() + hit->getPosZ())/2./mm
1651  << " Path [mm]: " << hit->getPathLength()/mm
1652  //<< " NDaughters: " << hit->getMCParticle()->getDaughters().size()
1653  //<< " VertexZ: " << *(hit->getMCParticle()->getVertex()+2)
1654  << std::resetiosflags(std::ios::showpos)
1655  << std::setprecision(0)
1656  << std::endl;
1657 }
1658 
1659 //
1660 // Method printing processor parameters
1661 //
1663 {
1664  streamlog_out(MESSAGE3) << std::endl
1665  << " "
1666  << DUNDERL
1667  << DBLUE
1668  << "SiStripDigi parameters:"
1669  << ENDCOLOR
1670  << " "
1671  << std::endl << std::endl;
1672 
1673  streamlog_out(MESSAGE3) << std::setiosflags(std::ios::fixed | std::ios::internal )
1674  << std::setprecision(2)
1675  << " Sensor depletion voltage [V]: " << std::setw(6) << _Vdepl/V << std::endl
1676  << " Sensor bias voltage [V]: " << std::setw(6) << _Vbias/V << std::endl
1677  << " Temperature set on sensor [K]: " << std::setw(6) << _temp/K << std::endl;
1678  if (_electronicEffects)
1679  streamlog_out(MESSAGE3) << " Mutual interstrip capacitance [pF]: " << std::setw(6) << _capInterStrip<< std::endl
1680  << " Strip-to-backplane capacitance [pF]: " << std::setw(6) << _capBackPlane << std::endl
1681  << " AC coupling - capacitance [pF]: " << std::setw(6) << _capCoupl << std::endl
1682  << " Electronics noise - ENC [fC]: " << std::setw(6) << _elNoise/fC << std::endl << std::endl;
1683  if (_floatStripsRPhi)
1684  streamlog_out(MESSAGE3) << " Read-out R-Phi pitch is 2x geom. pitch." << std::endl;
1685  if (_floatStripsZ)
1686  streamlog_out(MESSAGE3) << " Read-out Z pitch is 2x geom. pitch." << std::endl;
1687  if (_landauFluct) {
1688  streamlog_out(MESSAGE3) << " " << std::endl
1689  << " Internal Landau fluctuations?: " << " yes" << std::endl
1690  << " Prod. threhold on second. e [keV]: " << std::setw(6) << _prodThreshOnDeltaRays/keV << std::endl
1691  << " Beta*Gamma limit for Landau fluct: " << std::setw(6) << _landauBetaGammaCut << std::endl;
1692  }
1693  else {
1694  streamlog_out(MESSAGE3) << " " << std::endl
1695  << " Internal Landau fluctuations?: " << " no" << std::endl;
1696  }
1697  streamlog_out(MESSAGE3) << " " << std::endl
1698  << " Digi precision in space [um]: " << std::setw(6) << _epsSpace/um << std::endl
1699  << " Digi rel. precision in Lorentz angle: " << std::setw(6) << _epsAngle << std::endl
1700  << " Digi rel. precision in Drift time: " << std::setw(6) << _epsTime << std::endl
1701  << std::resetiosflags(std::ios::showpos)
1702  << std::setprecision(0)
1703  << std::endl;
1704 }
1705 
1706 //
1707 // Method printing info about signals at each strip
1708 //
1709 void SiStripDigi::printStripsInfo( std::string info, const SensorStripMap & sensorMap) const
1710 {
1711  // Sensor map of strips with total integrated charge
1712  SensorStripMap::const_iterator iterSMap;
1713  StripChargeMap::const_iterator iterChMap;
1714 
1715  int cellID = 0;
1716 
1717  short int layerID = 0;
1718  short int ladderID = 0;
1719  short int sensorID = 0;
1720 
1721  int stripID = 0;
1722 
1723  streamlog_out(MESSAGE1) << " Digi results - " << info
1724  << ":" << std::endl;
1725 
1726  for (iterSMap=sensorMap.begin(); iterSMap!=sensorMap.end(); ++iterSMap) {
1727 
1728  cellID = iterSMap->first;
1729  std::map<std::string,int> bfMap = _geometry->decodeCellID(cellID);
1730  layerID = bfMap["layer"];
1731  ladderID= bfMap["module"];
1732  sensorID= bfMap["sensor"];
1733  //_geometry->decodeCellID(layerID, ladderID, sensorID, cellID);
1734  layerID = _geometry->getLayerRealID(layerID);
1735 
1736  streamlog_out(MESSAGE1) << std::endl
1737  <<" Layer: " << layerID
1738  <<" Ladder: " << ladderID
1739  <<" Sensor: " << sensorID
1740  << std::endl;
1741 
1742  // Strips in R-Phi
1743  for (iterChMap=iterSMap->second[STRIPRPHI].begin(); iterChMap!=iterSMap->second[STRIPRPHI].end(); ++iterChMap) {
1744 
1745  stripID = iterChMap->first;
1746  streamlog_out(MESSAGE1) << " Strip number in R-Phi: " << stripID
1747  << std::setiosflags(std::ios::fixed | std::ios::internal )
1748  << std::setprecision(2)
1749  << " Total charge [fC]: " << iterChMap->second->getCharge() / fC
1750  //<< " Generation time [ns]: " << iterChMap->second->getTime()/ns
1751  << std::setprecision(0)
1752  << std::endl;
1753  }
1754 
1755  // Strips in Z
1756  for (iterChMap=iterSMap->second[STRIPZ].begin(); iterChMap!=iterSMap->second[STRIPZ].end(); ++iterChMap) {
1757 
1758  stripID = iterChMap->first;
1759  streamlog_out(MESSAGE1) << " Strip number in Z: " << stripID
1760  << std::setiosflags(std::ios::fixed | std::ios::internal )
1761  << std::setprecision(2)
1762  << " Total charge [fC]: " << iterChMap->second->getCharge() / fC
1763  //<< " Generation time [ns]: " << iterChMap->second->getTime()/ns
1764  << std::setprecision(0)
1765  << std::endl;
1766  }
1767  streamlog_out(MESSAGE1) << std::endl;
1768 
1769  } // For
1770 }
1771 
1772 } // Namespace
#define SEED
Definition: SiStripDigi.h:130
static const float mm
double getElecMobility(double pos)
Get method - returns ELECTRON mobility (parameters: electric intenzity in V/cm, respectively position...
void set3Position(const CLHEP::Hep3Vector &position)
Set cluster position Three vector.
Definition: DigiCluster.cc:44
virtual double getSensorThick(short int layerID) const
Get sensor thickness.
Definition: SiStripGeom.cc:421
double getElecDriftTime(double pos)
Get method - returns total ELECTRON drift time (parameters: electron position in cm).
double getElecDiffusivity(double pos)
Get method - returns ELECTRON diffusivity (parameters: electron mobility in cm^2/s, respectively position in cm).
static SiStripGeom * Build(const std::string &detector, const double &pitchFront, const double &pitchRear)
double _pitchRear
Pitch in the rear sensors (in the middle)
Definition: SiStripDigi.h:425
short int getLayerID() const
Get layer ID.
Definition: DigiCluster.h:151
virtual CLHEP::Hep3Vector transformPointToLocal(short int layerID, short int ladderID, short int sensorID, const CLHEP::Hep3Vector &point)=0
Transform given point from global ref. system to local ref. system (sensor)
double getCharge() const
Get signal.
Definition: Signal.h:56
double getPosZ() const
Get posStep position Z.
short int _currentLadderID
Actual ladder ID.
Definition: SiStripDigi.h:435
double getHoleDriftTime(double pos)
Get method - returns total HOLE drift time (parameters: hole position in cm).
#define STRIPZ
Definition: SiStripDigi.h:127
short int getLadderID() const
Get ladder ID.
CLHEP::Hep3Vector get3Step() const
Get step.
static const float um
#define DBLUE
Definition: Colours.h:16
void setLayerID(short int iLayer)
Set layer ID.
double _timeCPU
CPU time.
Definition: SiStripDigi.h:462
virtual CLHEP::Hep3Vector transformPointToRotatedLocal(const int &diskID, const int &sensorID, const CLHEP::Hep3Vector &point) const =0
Transforming a given point to the local ref.
double _pitchFront
Pitch in the front sensors (in the middle)
Definition: SiStripDigi.h:424
CLHEP::Hep3Vector get3PrePosition() const
Get preStep position Three vector.
double getElecVelocity(double pos)
Get method - returns ELECTRON actual velocity, calculated as follows:
virtual void init()
Method called at the beginning of data processing - used for initialization.
Definition: SiStripDigi.cc:207
void genNoise(SensorStripMap &sensorMap)
Method generating random noise using Gaussian distribution and add this effect to the final results...
#define STRIPFRONT
Definition: SiStripDigi.h:123
Digitization hit inheritad from LCIO SimTrackerHitImpl, which naturally extends basic features of Sim...
virtual void processEvent(LCEvent *event)
Method called for each event - used for event data processing.
Definition: SiStripDigi.cc:309
CLHEP::Hep3Vector get3Momentum() const
Get momentum Three vector.
virtual double getSensorLength(short int layerID) const
Get sensor length.
Definition: SiStripGeom.cc:467
static const float k
void digitize(const SimTrackerDigiHit *hit, SensorStripMap &sensorMap)
Method digitizing given SimTrackerDigiHit - takes into account all relevant physical processes: landa...
Definition: SiStripDigi.cc:795
float _capBackPlane
Strip-to-backplane capacitance.
Definition: SiStripDigi.h:409
void printProcessorParams() const
Method printing processor parameters.
#define ROUNDEPS
Definition: SiStripDigi.h:129
int _nRun
Run number.
Definition: SiStripDigi.h:463
#define ENDCOLOR
Definition: Colours.h:21
static const float V
Double precision Romberg integration solver (Template class represents class whose method is to be in...
Definition: RombIntSolver.h:31
std::map< int, StripChargeMap * > SensorStripMap
Definition: SiStripDigi.h:142
std::map< EVENT::SimTrackerHit *, float > SimTrackerHitMap
Definition: Signal.h:17
double getPreX() const
Get preStep position X.
void setDriftTime(double driftTime)
Set cluster total drift time.
Definition: DigiCluster.h:79
double getPosX() const
Get cluster position X.
Definition: DigiCluster.h:112
#define STRIPRPHI
Definition: SiStripDigi.h:126
static const float keV
SiEnergyFluct * _fluctuate
Definition: SiStripDigi.h:450
static const float us
const std::vector< std::string > ConstStringVec
Definition: SiStripClus.h:52
std::vector< DigiCluster * > DigiClusterVec
Definition: SiStripDigi.h:136
virtual void processRunHeader(LCRunHeader *run)
Method called for each run - used for run header processing.
Definition: SiStripDigi.cc:288
double _prodThreshOnDeltaRays
Production threshold cut on delta electrons in keV (for Landau fluct.) - use the same as in Geant4 (8...
Definition: SiStripDigi.h:422
bool _integrationWindow
Use integration window?
Definition: SiStripDigi.h:428
void setPrePosition(double pos[3], float momentum[3], float pathLength)
Set preStep position of a hit.
Signal class holds all information that one gets from strip, pixel, etc ...
Definition: Signal.h:24
static const float fC
#define DUNDERL
Definition: Colours.h:20
double getPosZ() const
Get cluster position Z.
Definition: DigiCluster.h:118
virtual std::string getGearType()
Get gear type.
Definition: SiStripGeom.h:87
CLHEP::Hep3Vector getHoleLorentzShift(double pos)
Method used for precise calculation of tan(Lorentz angle) - an angle of HOLES deflection due to magne...
void printStripsInfo(std::string info, const SensorStripMap &sensorMap) const
Method printing info about signals at each strip.
static const float T
virtual CLHEP::Hep3Vector get3MagField()
Get magnetic field - Three vector.
Definition: SiStripGeom.h:83
std::string _relColNamePlsToSim
LCIO relation collection name - TrkPulse (Digit) &lt;-&gt; SimTrkHit.
Definition: SiStripDigi.h:397
CLHEP::Hep3Vector _magField
Magnetic field in T in detector reference system.
Definition: SiStripDigi.h:441
float _elNoise
CMS-like (common mode subtracted) noise added to the signal.
Definition: SiStripDigi.h:411
double getPreY() const
Get preStep position Y.
double getElecInvVelocity(double pos)
Get method - returns actual ELECTRON inverse velocity, calculated as.
int _nEvent
Event number.
Definition: SiStripDigi.h:464
double getTime() const
Get time when signal was created.
Definition: Signal.h:59
double getStepSize() const
Get step size.
void setPosPosition(double pos[3], float momentum[3], float pathLength)
Set posStep position of a hit (parameters: preStep position, momentum at this position and total path...
static const float s
virtual bool isPointInsideSensor(short int layerID, short int ladderID, short int sensorID, const CLHEP::Hep3Vector &point) const =0
Get info whether the given point is inside of Si sensor.
double SampleFluctuations(const MCParticle *part, const double length)
Method providing energy loss fluctuations, the model used to get the fluctuations is essentially the ...
void transformSimHit(SimTrackerDigiHit *simDigiHit)
Method transforming given SimTrackerHit into local ref.
std::string _inColName
LCIO input collection name.
Definition: SiStripDigi.h:395
short int _currentSensorID
Actual sensor ID.
Definition: SiStripDigi.h:436
double _startIntegration
Start time of integration of the sensors in ns (everything before this value will not be digitized) ...
Definition: SiStripDigi.h:429
double _stopIntegration
Stop time of integration of the sensors in ns(everything after this value will not be digitized) ...
Definition: SiStripDigi.h:430
short int getLayerID() const
Get layer ID.
bool _floatStripsRPhi
Is every even strip floating in R-Phi?
Definition: SiStripDigi.h:412
Digitization cluster class.
Definition: DigiCluster.h:30
virtual void updateCanonicalCellID(const int &cellID, const int &stripType, const int &stripID, UTIL::BitField64 *bf)=0
Stores the cellID0 and cellID1 of the LCIO object to the file.
void setLadderID(short int iLadder)
Set ladder ID.
void printHitInfo(std::string info, const SimTrackerDigiHit *hit) const
Method printing hit info (parameter: info - extra information)
float _Vdepl
Sensor depletion voltage in volts.
Definition: SiStripDigi.h:403
void calcCrossTalk(SensorStripMap &sensorMap)
Method that calculates crosstalk effect, i.e.
void calcClusters(const SimTrackerDigiHit *hit, DigiClusterVec &hClusterVec)
Method that calculates e-h clusters, where clusters are worked out from the hits (simulated in Geant ...
Definition: SiStripDigi.cc:995
static const float ms
double getPosY() const
Get cluster position Y.
Definition: DigiCluster.h:115
void updateCharge(double charge)
Update signal.
Definition: Signal.h:41
static const float GeV
void printClustersInfo(std::string info, const DigiClusterVec &clusterVec) const
Method printing clusters info (parameter: info - extra information)
float _temp
Sensor temperature in Kelvins.
Definition: SiStripDigi.h:405
virtual int getStripID(const int &layerID, const int &sensorID, const double &posRPhi, const double &posZ) const =0
Get strip ID.
static const float e
float getTime() const
Get time when the cluster has been generated by a particle.
Definition: DigiCluster.h:136
static const float K
short int _currentLayerID
Actual layer ID.
Definition: SiStripDigi.h:434
float _epsTime
Relative digi precision in Drift time.
Definition: SiStripDigi.h:417
virtual int getSensorNStrips(const int &layerID, const int &sensorID) const =0
Get number of strips in Z axis (in each sensor)
double getPreZ() const
Get preStep position Z.
CLHEP::RandGauss * _genGauss
Random number generator - Gaussian distribution.
Definition: SiStripDigi.h:447
void setSensorID(short int iSensor)
Set sensor ID.
#define DGREEN
Definition: Colours.h:19
SiStripGeom * _geometry
All geometry information from Gear xml file.
Definition: SiStripDigi.h:444
virtual void check(LCEvent *event)
Method called after each event - used for data checking.
Definition: SiStripDigi.cc:739
bool _floatStripsZ
Is every even strip floating in Z?
Definition: SiStripDigi.h:413
CLHEP::Hep3Vector getElecLorentzShift(double posZ)
Method used for precise calculation of tan(Lorentz angle) - an angle of ELECTRON deflection due to ma...
float _sensorThick
Actual sensor - Si wafer thickness in system of units.
Definition: SiStripDigi.h:437
bool _landauFluct
Define if internal Landau fluctuations (instead of Geant4) used.
Definition: SiStripDigi.h:420
void updateSimHitMap(EVENT::SimTrackerHit *simHit, float weight)
Update MC truth information about SimTrackerHits, which contributed.
Definition: Signal.cc:19
static const float ePlus
double getHoleInvVelocity(double pos)
Get method - returns actual HOLE inverse velocity, calculated as follows:
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
void setMomentum(float p[3])
Set particle momentum at preStep position.
double Integrate(double endPointA, double endPointB)
This method returns a definite integral of function fce calculated in interval (a,b) using so-called Romberg algorithm.
Special class providing particle energy loss fluctuations in Si material (Landau fluctuations).
Definition: SiEnergyFluct.h:63
float _landauBetaGammaCut
Below this beta*gamma factor internal Landau fluctuations not used.
Definition: SiStripDigi.h:421
std::string _outColName
LCIO output collection name.
Definition: SiStripDigi.h:396
void printClusterInfo(const DigiCluster &cluster) const
Method printing cluster info.
virtual double getLayerHalfPhi(const int &layerID) const
Get layer semiangle.
Definition: SiStripGeom.cc:199
CLHEP::Hep3Vector get3PosPosition() const
Get posStep position Three vector.
double getHoleVelocity(double pos)
Get method - returns HOLE actual velocity, calculated as follows:
std::map< int, Signal * > StripChargeMap
Definition: SiStripDigi.h:141
float _Vbias
Sensor bias voltage in volts.
Definition: SiStripDigi.h:404
virtual void initGearParams()=0
Method initializing class - reads Gear parameters from XML file Pure virtual method, have to be implemented by a concrete instance.
std::string _subdetector
Definition: SiStripDigi.h:401
double getEField(double pos)
Get method - returns electric intensity (parameters: position X in cm).
#define STRIPREAR
Definition: SiStripDigi.h:124
#define DYELLOW
Definition: Colours.h:18
short int getSensorID() const
Get sensor ID.
Definition: DigiCluster.h:157
virtual double getSensorPitch(const int &layerID, const int &sensorID, const double &posZ) const =0
Get sensor pitch.
float _epsAngle
Relative digi precision in Lorentz angle.
Definition: SiStripDigi.h:416
static const float cm
float _capCoupl
AC coupling - capacitance.
Definition: SiStripDigi.h:410
void set3PrePosition(const CLHEP::Hep3Vector &prePosition)
Set preStep position Three vector.
void set3PosPosition(const CLHEP::Hep3Vector &posPosition)
Set posStep Three vector.
static const float ns
virtual std::map< std::string, int > decodeCellID(const UTIL::BitField64 &cellDec) const =0
Encode cellID.
int getCellID() const
Get cell ID.
Definition: DigiCluster.h:160
virtual int getLayerRealID(short int layerID) const
Get layer real ID.
Definition: SiStripGeom.cc:123
EVENT::SimTrackerHit * getSimTrackerHit() const
Get pointer to SimTrackerHit from which the given cluster has been created.
Definition: DigiCluster.h:166
double getHoleMobility(double pos)
Get method - returns HOLE mobility (parameters: electric intenzity in V/cm, respectively position X i...
float _epsSpace
Absolute digi precision in space in um.
Definition: SiStripDigi.h:415
bool _electronicEffects
Add crosstalk + noise?
Definition: SiStripDigi.h:407
virtual CLHEP::Hep3Vector transformVecToLocal(short int layerID, short int ladderID, short int sensorID, const CLHEP::Hep3Vector &vec)=0
Transform given vector from global ref. system to local ref. system (sensor)
EVENT::SimTrackerHit * getSimTrackerHit() const
Get original SimTrackerHit.
SiStripDigi anSiStripDigi
Definition: SiStripDigi.cc:54
double getHoleDiffusivity(double pos)
Get method - returns HOLE diffusivity (parameters: hole mobility in cm^2/s, respectively position in ...
void set3Momentum(const CLHEP::Hep3Vector &momentum)
Set particle Three momentum.
virtual void end()
Method called after all data processing.
Definition: SiStripDigi.cc:746
void setSimTrackerHit(EVENT::SimTrackerHit *simHit)
Set original SimTrackerHit.
float _capInterStrip
Mutual interstrip capacitance.
Definition: SiStripDigi.h:408
double getPosY() const
Get posStep position Y.
const SimTrackerHitMap & getSimHitMap() const
Get MC truth information about SimTrackerHits, which contributed.
Definition: Signal.h:62
double getPosX() const
Get posStep position X.
short int getSensorID() const
Get sensor ID.
short int getCharge() const
Get cluster charge.
Definition: DigiCluster.h:145
int getNCarriers() const
Get number of charge carriers.
Definition: DigiCluster.h:148