ATLAS Offline Software
SCT_FastDigitizationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 // Pile-up
9 
10 // Hit class includes
12 #include "Identifier/Identifier.h"
13 #include "InDetIdentifier/SCT_ID.h"
14 
15 // Det Descr includes
17 
22 
23 // FATRAS
25 #include "TrkSurfaces/Surface.h"
33 
35 
36 // Gaudi
37 #include "GaudiKernel/SystemOfUnits.h"
38 
40 #include "AtlasHepMC/GenParticle.h"
41 
42 // CLHEP
44 #include "CLHEP/Random/RandomEngine.h"
45 #include "CLHEP/Random/RandGaussZiggurat.h"
46 #include "CLHEP/Random/RandLandau.h"
47 
48 #include <algorithm>
49 #include <cmath>
50 #include <memory>
51 #include <sstream>
52 #include <string>
53 
55  const std::string& name,
56  const IInterface* parent) :
57 
59 {
60 }
61 
62 //----------------------------------------------------------------------
63 // Initialize method:
64 //----------------------------------------------------------------------
66 {
67 
68  //locate the AtRndmGenSvc and initialize our local ptr
69  CHECK(m_rndmSvc.retrieve());
70 
71  CHECK(detStore()->retrieve(m_sct_ID, "SCT_ID"));
72 
73  if (m_inputObjectName=="")
74  {
75  ATH_MSG_FATAL ( "Property InputObjectName not set !" );
76  return StatusCode::FAILURE;
77  }
78  else
79  {
80  ATH_MSG_DEBUG ( "Input objects: '" << m_inputObjectName << "'" );
81  }
84 
85  // retrieve the offline cluster maker : for pixel and/or sct
86  if (!m_clusterMaker.empty())
87  {
88  CHECK(m_clusterMaker.retrieve());
89  }
90 
91  //locate the PileUpMergeSvc and initialize our local ptr
92  CHECK(m_mergeSvc.retrieve());
93 
94  CHECK(m_lorentzAngleTool.retrieve());
95  //Initialize threshold
97 
98  // Initialize ReadCondHandleKey
100 
101  return StatusCode::SUCCESS ;
102 }
103 
104 StatusCode SCT_FastDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
105 {
106 
107  m_siHitCollList.clear();
110  return StatusCode::SUCCESS;
111 
112 }
113 
115  SubEventIterator bSubEvents,
116  SubEventIterator eSubEvents)
117 {
118  //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
119  if (m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
120  if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
122 
123  using TimedHitCollList = PileUpMergeSvc::TimedList<SiHitCollection>::type;
124  TimedHitCollList hitCollList;
125 
126  if (!(m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName.value(), hitCollList, bunchXing,
127  bSubEvents, eSubEvents).isSuccess()) &&
128  hitCollList.empty()) {
129  ATH_MSG_ERROR("Could not fill TimedHitCollList");
130  return StatusCode::FAILURE;
131  } else {
132  ATH_MSG_VERBOSE(hitCollList.size() << " SiHitCollections with key " <<
133  m_inputObjectName << " found");
134  }
135 
136  TimedHitCollList::iterator iColl(hitCollList.begin());
137  TimedHitCollList::iterator endColl(hitCollList.end());
138 
139  for( ; iColl != endColl; ++iColl) {
140  SiHitCollection *siHitColl = new SiHitCollection(*iColl->second);
141  PileUpTimeEventIndex timeIndex(iColl->first);
142  ATH_MSG_DEBUG("SiHitCollection found with " << siHitColl->size() <<
143  " hits");
144  ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
145  << " index: " << timeIndex.index()
146  << " type: " << timeIndex.type());
147  m_thpcsi->insert(timeIndex, siHitColl);
148  m_siHitCollList.push_back(siHitColl);
149  }
150 
151  return StatusCode::SUCCESS;
152 }
153 
154 
156 
157  // get the container(s)
158  using TimedHitCollList = PileUpMergeSvc::TimedList<SiHitCollection>::type;
159 
160  //this is a list<pair<time_t, DataLink<SCTUncompressedHitCollection> > >
161  TimedHitCollList hitCollList;
162  unsigned int numberOfSimHits(0);
163  if ( !(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName.value(), hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() )
164  {
165  ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
166  return StatusCode::FAILURE;
167  }
168  else
169  {
170  ATH_MSG_DEBUG ( hitCollList.size() << " SiHitCollections with key " << m_inputObjectName << " found" );
171  }
172 
173  // Define Hit Collection
174  TimedHitCollection<SiHit> thpcsi(numberOfSimHits);
175 
176  //now merge all collections into one
177  TimedHitCollList::iterator iColl(hitCollList.begin());
178  TimedHitCollList::iterator endColl(hitCollList.end() );
179 
181  // loop on the hit collections
182  while ( iColl != endColl )
183  {
184  //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
186  if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
188  const SiHitCollection* p_collection(iColl->second);
189  thpcsi.insert(iColl->first, p_collection);
190  ATH_MSG_DEBUG ( "SiHitCollection found with " << p_collection->size() << " hits" );
191  ++iColl;
192  }
193 
194  // Process the Hits
195  CHECK(this->digitize(ctx, thpcsi));
196 
197  CHECK(this->createAndStoreRIOs(ctx));
198  ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
199 
200  return StatusCode::SUCCESS;
201 }
202 
203 
204 
206 {
207  if (m_thpcsi != nullptr)
208  {
209  CHECK(this->digitize(ctx, *m_thpcsi));
210  }
211 
212  //-----------------------------------------------------------------------
213  // Clean up temporary containers
214  delete m_thpcsi;
215  for(SiHitCollection* ptr : m_siHitCollList) delete ptr;
216  m_siHitCollList.clear();
217  //-----------------------------------------------------------------------
218 
219  CHECK(this->createAndStoreRIOs(ctx));
220  ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
221 
222  return StatusCode::SUCCESS;
223 }
224 
225 
228 {
229  // truth info
231  sctPrdTruth = std::make_unique< PRD_MultiTruthCollection >();
232  if ( !sctPrdTruth.isValid() ) {
233  ATH_MSG_FATAL( "Could not record collection " << sctPrdTruth.name() );
234  return StatusCode::FAILURE;
235  }
236  ATH_MSG_DEBUG( "PRD_MultiTruthCollection " << sctPrdTruth.name() << " registered in StoreGate" );
237 
238  // Set the RNG to use for this event.
239  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
240  const std::string rngName = name()+m_randomEngineName;
241  rngWrapper->setSeed( rngName, ctx );
242  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
243 
244  // Get SCT_DetectorElementCollection
246  const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
247  if (elements==nullptr) {
248  ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
249  return StatusCode::FAILURE;
250  }
251 
254  else { m_sctClusterMap->clear(); }
255  while (thpcsi.nextDetectorElement(i, e))
256  {
257  SCT_detElement_RIO_map SCT_DetElClusterMap;
258  std::vector<int> truthIdList;
259  std::vector<Identifier> detEl;
260  while (i != e)
261  {
262  const TimedHitPtr<SiHit>& currentSiHit(*i++);
263  // check the status of truth information for this SiHit
264  // some Truth information is cut for pile up events
265  const HepMcParticleLink currentLink = HepMcParticleLink::getRedirectedLink(currentSiHit->particleLink(), currentSiHit.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
266 
267  const Identifier waferId = m_sct_ID->wafer_id(currentSiHit->getBarrelEndcap(), currentSiHit->getLayerDisk(), currentSiHit->getPhiModule(), currentSiHit->getEtaModule(), currentSiHit->getSide());
268  const IdentifierHash waferHash = m_sct_ID->wafer_hash(waferId);
269  const InDetDD::SiDetectorElement *hitSiDetElement = elements->getDetectorElement(waferHash);
270  if (!hitSiDetElement)
271  {
272  ATH_MSG_ERROR( "Could not get detector element.");
273  continue;
274  }
275 
276  // the module design
277  const InDetDD::SCT_ModuleSideDesign* design = dynamic_cast<const InDetDD::SCT_ModuleSideDesign*>(&hitSiDetElement->design());
278  if (!design)
279  {
280  ATH_MSG_WARNING ( "SCT_DetailedSurfaceChargesGenerator::process can not get "<< design) ;
281  continue;
282  }
283 
284  std::vector<HepMcParticleLink> hit_vector; //Store the hits in merged cluster
285 
286  // Process only one hit by the same particle in the same detector element
287  bool isRep = false;
288  const int truthID = (currentLink.barcode() !=0 && currentLink.id() == 0) ? 3 : currentLink.id(); // FIXME barcode-based Patch for reading in legacy barcode-based EDM - if the barcode is non-zero, but the id is zero then we must be looking at a particle linked to suppressed pile-up truth - such SiHits would be linked to the third GenParticle in their GenEvents (if they were present)
289  const Identifier detElId = hitSiDetElement->identify();
290  for (int j : truthIdList)
291  {
292  for (auto & k : detEl)
293  {
294  if ((truthID > 0) && (truthID == j) && (detElId == k)) {isRep = true; break;}
295  }
296  if (isRep) { break; }
297  }
298  if (isRep) { continue; }
299  truthIdList.push_back(truthID);
300  detEl.push_back(detElId);
301 
302  const double hitDepth = hitSiDetElement->hitDepthDirection();
303 
304  double shiftX,shiftY;
305  if (hitSiDetElement->isBarrel()){
308  }
309  else{
312  }
313 
314  HepGeom::Point3D<double> localStartPosition = hitSiDetElement->hitLocalToLocal3D(currentSiHit->localStartPosition());
315  HepGeom::Point3D<double> localEndPosition = hitSiDetElement->hitLocalToLocal3D(currentSiHit->localEndPosition());
316 
317  Diffuse(localStartPosition,localEndPosition, shiftX * Gaudi::Units::micrometer, shiftY * Gaudi::Units::micrometer);
318 
319  const double localEntryX = localStartPosition.x();
320  const double localEntryY = localStartPosition.y();
321  const double localEntryZ = localStartPosition.z();
322  const double localExitX = localEndPosition.x();
323  const double localExitY = localEndPosition.y();
324  const double localExitZ = localEndPosition.z();
325 
326 
327 
328  const Amg::Vector2D localEntry(localEntryX,localEntryY);
329  const Amg::Vector2D localExit(localExitX,localExitY);
330  const Amg::Vector3D localExit3D(localExitX,localExitY,localExitZ);
331 
332  const double thickness = hitSiDetElement->thickness();
333 
334  const Trk::Surface *hitSurface = &hitSiDetElement->surface();
335 
336  const double distX = localExitX-localEntryX;
337  const double distY = localExitY-localEntryY;
338  const double distZ = localExitZ-localEntryZ;
339 
340  const Amg::Vector3D localDirection(distX, distY, distZ);
341  // path length statistics
342  double potentialClusterPath_Geom = localDirection.mag(); // geometrical path length
343  double potentialClusterPath_Step = 0.; // path calculated through stepping
344  double potentialClusterPath_Used = 0.; // path used (contains smearing & cut if applied)
345 
346  // relational slope
347  const double slopeYX = distY/distX;
348  const double slopeXZ = distX/distZ;
349  const double slopeZX = distZ/distX;
350  // signs of stepping
351  const int signX = distX > 0. ? 1 : -1 ;
352  const int signY = distY > 0. ? 1 : -1 ;
353  const int signZ = distZ > 0. ? 1 : -1 ;
354 
355  // get the identifier of the entry and the exit
356  const Identifier entryId = hitSiDetElement->identifierOfPosition(localEntry);
357  const Identifier exitId = hitSiDetElement->identifierOfPosition(localExit);
358  // now get the cellIds and check whether they're valid
359  const InDetDD::SiCellId entryCellId = hitSiDetElement->cellIdFromIdentifier(entryId);
360  const InDetDD::SiCellId exitCellId = hitSiDetElement->cellIdFromIdentifier(exitId);
361  // entry / exit validity
362  const bool entryValid = entryCellId.isValid();
363  const bool exitValid = exitCellId.isValid();
364 
365  // the intersecetion id and cellId of it
366  const double par = -localEntryZ/(localExitZ-localEntryZ);
367  const double interX = localEntryX + par*(localExitX-localEntryX);
368  const double interY = localEntryY + par*(localExitY-localEntryY);
369 
370  const Amg::Vector2D intersection(interX,interY);
371  const Identifier intersectionId = hitSiDetElement->identifierOfPosition(intersection);
372 
373  // apply the lorentz correction
374  const IdentifierHash detElHash = hitSiDetElement->identifyHash();
375  const double tanLorAng = m_sctTanLorentzAngleScalor*m_lorentzAngleTool->getTanLorentzAngle(detElHash);
376  const int lorentzDirection = tanLorAng > 0. ? 1 : -1;
377  const bool useLorentzDrift = std::abs(tanLorAng) > 0.01;
378  // shift parameters
379  const double shift = m_lorentzAngleTool->getLorentzShift(detElHash);
380  // lorenz angle effects : offset goes against the lorentzAngle
381  const double xLoffset = -lorentzDirection*thickness*tanLorAng;
382 
383  // --------------------------------------------------------------------------------------
384  // fast exit: skip non-valid entry && exit
385  if (!entryValid && !exitValid)
386  {
387  continue;
388  }
389 
390  std::vector<Identifier> potentialClusterRDOList;
391  std::map<Identifier, double> surfaceChargeWeights;
392  // min/max indices
393  int phiIndexMinRaw = 1000;
394  int phiIndexMaxRaw = -1000;
395 
396  // is it a single strip w/o drift effect ? - also check the numerical stability
397  const bool singleStrip = (entryCellId == exitCellId && entryValid);
398  if (singleStrip && !useLorentzDrift)
399  {
400  // ----------------------- single strip lucky case ----------------------------------------
401  // 1 strip cluster without drift effect
402  surfaceChargeWeights[intersectionId] = potentialClusterPath_Geom;
403  }
404  else
405  {
406  // the start parameters
407  int strips = 0;
408  // needed for both approaches with and w/o drift
409  Identifier currentId = entryId;
410  InDetDD::SiCellId currentCellId = entryCellId;
411  Amg::Vector2D currentCenterPosition = hitSiDetElement->rawLocalPositionOfCell(currentCellId);
412  Amg::Vector3D currentPosition3D(localEntryX,localEntryY,localEntryZ);
413  Amg::Vector3D currentStep3D(0.,0.,0.);
414 
415  // ============================== the clusteristiaon core =====================================================
416  // ----------------------- barrel geometrical clustering with drift -------------------------------------------
417  // there are two independent loops
418  // (a) the geometrical steps through the strips : labelled current
419  Amg::Vector2D currentCenterStep(0.,0.);
420  // check for non-valid entry diode ... this needs to be reset then
421  // ---------------------------------------------------
422  // start position needs to be reset : --------
423  if (!entryValid)
424  {
425  // the number of strips in Phi
426  const int numberOfDiodesPhi = design->cells();
427  // the simple case is if the exit is outside locY
428  if (!hitSurface->bounds().insideLoc2(localEntry))
429  {
430  // step towards the border
431  const double stepInY = signY*(std::abs(localEntryY)-0.5*hitSiDetElement->length());
432  const double stepInX = stepInY*distX/distY;
433  const double stepInZ = stepInY*distZ/distY;
434  currentStep3D = Amg::Vector3D(stepInX,stepInY,stepInZ);
435  }
436  else
437  {
438  //get the last valid phi border
439  const int phiExitIndex = exitCellId.phiIndex() <= 2 ? 0 : numberOfDiodesPhi-1;
440 
441  const InDetDD::SiCellId phiExitId(phiExitIndex);
442  const Amg::Vector2D phiExitCenter = hitSiDetElement->rawLocalPositionOfCell(phiExitId);
443  // fill the step parameters
444  // this may need to be changed to Rectangular/Trapezoid check
445  currentStep3D = stepToStripBorder(*hitSiDetElement,
446  //*hitSurface,
447  localEntryX, localEntryY,
448  localExitX, localExitY,
449  slopeYX,
450  slopeZX,
451  phiExitCenter,
452  signX);
453  } // ENDIF !hitSurface->bounds().insideLoc2(localEntry)
454 
455  // get to the first valid strip ---------------------------------------------------
456  currentPosition3D += currentStep3D;
457  // for the record
458  potentialClusterPath_Step += currentStep3D.mag();
459  ATH_MSG_VERBOSE("[ cluster - sct ] Strip entry shifted by " << currentStep3D << " ( " << potentialClusterPath_Step << " )");
460  // for step epsilon into the first valid
461  const Amg::Vector2D positionInFirstValid(currentPosition3D.x()+0.01*signX,currentPosition3D.y()+0.01*signY);
462  // reset the entry parameters to the first valid pixel
463  currentId = hitSiDetElement->identifierOfPosition(positionInFirstValid);
464  currentCellId = hitSiDetElement->cellIdFromIdentifier(currentId);
465  currentCenterPosition = hitSiDetElement->rawLocalPositionOfCell(currentId);
466 
467  } // ----- start position has been reset -------- ( // endif (!entryValid) )
468 
469  // (b) the collection of strips due to surface charge
470  // the lorentz plane setp
471  double lplaneStepX = 0.;
472  double lplaneStepY = 0.;
473  Amg::Vector3D lplaneIntersection(0.,0.,0.);
474  Amg::Vector3D driftPrePosition3D(currentPosition3D);
475  Amg::Vector3D driftPostPosition3D(currentPosition3D);
476  // (c) simple cache for the purely geometrical clustering
477  Identifier lastId = currentId;
478  bool lastStrip = false;
479  ATH_MSG_VERBOSE("[ cluster - sct ] CurrentPosition " << currentPosition3D );
480 
481  // the steps between the strips -------------------------------------------
482  for ( ; ; ++strips)
483  {
484  // -------------------------------------------------------------------------------------------------
485  // current phi/eta indices
486  const int currentPhiIndex = currentCellId.phiIndex();
487  // record for the full validation
488  // (a) steps through the strips
489  // sct break for last strip or if you step out of the game
490  if (lastStrip || currentPosition3D.z() > 0.5*thickness || strips > 4)
491  {
492  break;
493  }
494  // no single valid strip
495  if (!exitValid && !currentCellId.isValid())
496  {
497  break;
498  }
499  // cache it
500  phiIndexMinRaw = currentPhiIndex < phiIndexMinRaw ? currentPhiIndex : phiIndexMinRaw;
501  phiIndexMaxRaw = currentPhiIndex > phiIndexMaxRaw ? currentPhiIndex : phiIndexMaxRaw;
502  // find out if this is the last step
503  lastStrip = (currentPhiIndex == exitCellId.phiIndex());
504  // get the current Pitch
505  const double currentPitchX = hitSiDetElement->phiPitch(currentCenterPosition);
506  // the next & previous sct borders are needed (next is w.r.t to the track direction)
507  std::vector<double> lorentzLinePositions;
508  const int trackDir = slopeXZ > 0 ? 1 : -1; //FIXME will be multiplying doubles by this int!
509  lorentzLinePositions.reserve(2);
510  // the both pixel borders left/right
511  lorentzLinePositions.push_back(currentCenterPosition.x() + trackDir*0.5*currentPitchX);
512  lorentzLinePositions.push_back(currentCenterPosition.x() - trackDir*0.5*currentPitchX);
513  // the third line is possible -> it is due to xOffset > pitchX
514  if (xLoffset*xLoffset > currentPitchX*currentPitchX)
515  {
516  lorentzLinePositions.push_back(currentCenterPosition.x() + lorentzDirection*1.5*currentPitchX);
517  }
518  // intersect the effective lorentz plane if the intersection is not valid anymore
519  bool lplaneInterInCurrent(false);
520  double lorentzPlaneHalfX(0.);
521  Amg::Vector3D lplaneCandidate(0.,0.,0.);
522  std::vector<double>::iterator lorentzLinePosIter = lorentzLinePositions.begin();
523  // find the intersection solutions for the three cases
524  int lplaneDirection = 100; // solve the intersection case first
525  // test left and right lorentz planes of this pixel
526  for ( ; lorentzLinePosIter != lorentzLinePositions.end(); ++lorentzLinePosIter)
527  {
528  // first - do the intersection : the readout side is respected by the hit depth direction
529  Trk::LineIntersection2D intersectLorentzPlane(localEntryX,-0.5*signZ*thickness,localExitX,0.5*signZ*thickness,
530  (*lorentzLinePosIter)+xLoffset,-0.5*hitDepth*thickness,
531  (*lorentzLinePosIter),0.5*hitDepth*thickness);
532  // avoid repeating intersections
533  const double formerPlaneStepZ = intersectLorentzPlane.interY-lplaneIntersection.z();
534  if (formerPlaneStepZ*formerPlaneStepZ < 10e-5)
535  {
536  lplaneInterInCurrent = false;
537  continue;
538  }
539  // is the intersection within the z thickness ?
540  lplaneInterInCurrent = intersectLorentzPlane.interY > -0.5*thickness
541  && intersectLorentzPlane.interY < 0.5*thickness;
542  // the step in z from the former plane intersection
543  // only go on if it is worth it
544  // (a) it has to be within z boundaries
545  if (lplaneInterInCurrent)
546  {
547  // record: the half position of the loretnz plane - for estimation to be under/over
548  lorentzPlaneHalfX = (*lorentzLinePosIter)+0.5*xLoffset;
549  // plane step parameters
550  lplaneStepX = intersectLorentzPlane.interX-localEntryX;
551  lplaneStepY = lplaneStepX*slopeYX;
552  // todo -> break condition if you are hitting the same intersection
553  lplaneCandidate = Amg::Vector3D(intersectLorentzPlane.interX,
554  localEntryY+lplaneStepY,
555  intersectLorentzPlane.interY);
556  // check in y, the x direction is only needed to find out the drift direction
557  const double distToNextLineY = 0.5*hitSiDetElement->length()-lplaneCandidate.y();
558  const double distToPrevLineY = -0.5*hitSiDetElement->length()-lplaneCandidate.y();
559  lplaneInterInCurrent = (distToNextLineY*distToPrevLineY) < 0.;
560  // we have an intersection candidate - needs to be resolved for +1/-1
561  lplaneDirection = lplaneInterInCurrent ? 0 : lplaneDirection;
562  if (lplaneInterInCurrent) {break;}
563  }
564  }
565  // now assign it (if valid)
566  if (lplaneInterInCurrent) {lplaneIntersection = lplaneCandidate;}
567  ATH_MSG_VERBOSE( "[ cluster - pix ] Lorentz plane intersection x/y/z = "
568  << lplaneCandidate.x() << ", "
569  << lplaneCandidate.y() << ", "
570  << lplaneCandidate.z() );
571 
572  // now solve for 1 / -1 if needed
573  if (lplaneDirection)
574  {
575  // check the z position of the track at this stage
576  const double trackZatlplaneHalfX = (lorentzPlaneHalfX-localEntryX)*slopeXZ - 0.5*thickness;
577  lplaneDirection = trackZatlplaneHalfX < 0. ? -1 : 1;
578  }
579 
580  // record the lorentz plane intersections
581  // calculate the potential step in X and Y
582  currentStep3D = lastStrip ? localExit3D-currentPosition3D :
583  stepToStripBorder(*hitSiDetElement,
584  //*hitSurface,
585  currentPosition3D.x(), currentPosition3D.y(),
586  localExitX, localExitY,
587  slopeYX,
588  slopeZX,
589  currentCenterPosition,
590  signX);
591 
592  // add the current Step to the current position
593  currentPosition3D += currentStep3D;
594  // check whether the step has led outside
595  if (!hitSurface->bounds().insideLoc2(Amg::Vector2D(currentPosition3D.x(),
596  currentPosition3D.y())))
597  { // stepping outside in y calls for last step
598  lastStrip = true;
599  // correct to the new position
600  currentPosition3D -= currentStep3D;
601  const double stepInY = signY*0.5*hitSiDetElement->length()-currentPosition3D.y();
602  const double stepInX = distX/distY*stepInY;
603  const double stepInZ = slopeZX*stepInX;
604  // update to the new currentStep
605  currentStep3D = Amg::Vector3D(stepInX,stepInY,stepInZ);
606  currentPosition3D += currentStep3D;
607  }
608  // if (currentPosition3D.z() > 0.501*signZ*thickness){
609  if (std::abs(currentPosition3D.z()) > 0.501*thickness)
610  {
611  // step has led out of the silicon, correct for it
612  lastStrip = true;
613  // correct to the new position (has been seen only three times ... probably numerical problem)
614  currentPosition3D -= currentStep3D;
615  currentStep3D = localExit3D-currentPosition3D;
616  currentPosition3D = localExit3D;
617  //
618  ATH_MSG_VERBOSE("[ cluster - sct ] - current position set to local Exit position !");
619  }
620 
621  // update the current values for the next step
622  const Amg::Vector2D currentInsidePosition(currentPosition3D.x()+0.01*signX,currentPosition3D.y()+0.01*signY);
623  currentId = hitSiDetElement->identifierOfPosition(currentInsidePosition);
624  currentCellId = hitSiDetElement->cellIdFromIdentifier(currentId);
625  // just to be sure also for fan structure cases
626  currentCenterPosition = hitSiDetElement->rawLocalPositionOfCell(currentCellId);
627  // The new current Position && the path length for monitoring
628  potentialClusterPath_Step += currentStep3D.mag();
629  ATH_MSG_VERBOSE("[ cluster - sct ] CurrentPosition " << currentPosition3D
630  << " ( yielded by :" << currentStep3D << ")");
631  // setting the drift Post position
632  driftPostPosition3D = lplaneInterInCurrent ? lplaneIntersection : currentPosition3D;
633  // ---------- the surface charge is emulated -------------------------------------------------------
634  if (m_sctEmulateSurfaceCharge && useLorentzDrift)
635  {
636  // loop to catch lpintersection in last step
637  const int currentDrifts = (lastStrip && lplaneInterInCurrent) ? 2 : 1;
638  for (int idrift = 0; idrift < currentDrifts; ++idrift)
639  {
640  // const assignment for fast access, take intersection solution first, then cell exit
641  const Amg::Vector3D& currentDriftPrePosition = idrift ? driftPostPosition3D : driftPrePosition3D;
642  const Amg::Vector3D& currentDriftPostPosition = idrift ? localExit3D : driftPostPosition3D;
643  // get the center of the step and drift it to the surface
644  const Amg::Vector3D driftStepCenter = 0.5*(currentDriftPrePosition+currentDriftPostPosition);
645  // respect the reaout side through the hit dept direction
646  const double driftZtoSurface = 0.5*hitDepth*thickness-driftStepCenter.z();
647  // record the drift position on the surface
648  const double driftPositionAtSurfaceX = driftStepCenter.x() + tanLorAng*driftZtoSurface;
649  const Amg::Vector2D driftAtSurface(driftPositionAtSurfaceX,
650  driftStepCenter.y());
651  const Identifier surfaceChargeId = hitSiDetElement->identifierOfPosition(driftAtSurface);
652  if (surfaceChargeId.is_valid())
653  {
654  // check if the pixel has already got some charge
655  if (surfaceChargeWeights.find(surfaceChargeId) == surfaceChargeWeights.end())
656  {
657  surfaceChargeWeights[surfaceChargeId] = (currentDriftPostPosition-currentDriftPrePosition).mag();
658  }
659  else
660  {
661  surfaceChargeWeights[surfaceChargeId] += (currentDriftPostPosition-currentDriftPrePosition).mag();
662  }
663  }
664  // record the drift step for validation
665  } // end of last step intersection check
666  }
667  else // ---------- purely geometrical clustering w/o surface charge ---------------------------
668  {
669  surfaceChargeWeights[lastId] = currentStep3D.mag();
670  }
671  // next pre is current post && lastId is currentId
672  driftPrePosition3D = driftPostPosition3D;
673  lastId = currentId;
674 
675  } // end of steps between strips ----------------------------------------------------------------------
676  }
677 
678  // the calculated local position
679  double totalWeight = 0.;
680  Amg::Vector2D potentialClusterPosition(0.,0.);
681  std::map<Identifier,double>::iterator weightIter = surfaceChargeWeights.begin();
682  for ( ; weightIter != surfaceChargeWeights.end(); ++weightIter)
683  {
684  // get the (effective) path length in the strip
685  double chargeWeight = (weightIter)->second;
686  const Identifier chargeId = (weightIter)->first;
687  // charge smearing if set : 2 possibilities landau/gauss
688  // two options fro charge smearing: landau / gauss
689  if ( m_sctSmearPathLength > 0. )
690  {
691  // create the smdar parameter
692  const double sPar = m_sctSmearLandau ?
693  m_sctSmearPathLength*CLHEP::RandLandau::shoot(rndmEngine) :
694  m_sctSmearPathLength*CLHEP::RandGaussZiggurat::shoot(rndmEngine);
695  chargeWeight *= (1.+sPar);
696  }
697 
698  // the threshold cut
699  if (!(chargeWeight > m_sctMinimalPathCut)) { continue; }
700 
701  // get the position according to the identifier
702  const Amg::Vector2D chargeCenterPosition = hitSiDetElement->rawLocalPositionOfCell(chargeId);
703  potentialClusterPath_Used += chargeWeight;
704  // taken Weight (Fatras can do analog SCT clustering)
705  const double takenWeight = m_sctAnalogStripClustering ? chargeWeight : 1.;
706  totalWeight += takenWeight;
707  potentialClusterPosition += takenWeight * chargeCenterPosition;
708  // and record the rdo
709  potentialClusterRDOList.push_back(chargeId);
710  }
711  // bail out - no left overs after cut
712 
713  if (potentialClusterRDOList.empty() || potentialClusterPath_Used < m_sctMinimalPathCut)
714  {
715  continue;
716  }
717 
718 
719 
720  // ---------------------------------------------------------------------------------------------
721  // PART 2: Cluster && ROT creation
722  //
723  // the Cluster Parameters -----------------------------
724  // normalize cluster position && get identifier
725  potentialClusterPosition *= 1./totalWeight;
726  /*const */Identifier potentialClusterId = hitSiDetElement->identifierOfPosition(potentialClusterPosition);
727  if (!potentialClusterId.is_valid()) {continue;}
728 
729  const IdentifierHash waferID = m_sct_ID->wafer_hash(hitSiDetElement->identify());
730 
731  // merging clusters
732  if(m_mergeCluster){
733  unsigned int countC(0);
734  ATH_MSG_INFO("Before cluster merging there were " << SCT_DetElClusterMap.size() << " clusters in the SCT_DetElClusterMap.");
735  for(SCT_detElement_RIO_map::iterator existingClusterIter = SCT_DetElClusterMap.begin(); existingClusterIter != SCT_DetElClusterMap.end();)
736  {
737  ++countC;
738  if (countC>100)
739  {
740  ATH_MSG_WARNING("Over 100 clusters checked for merging - bailing out!!");
741  break;
742  }
743  if (m_sct_ID->wafer_hash(((existingClusterIter->second)->detectorElement())->identify()) != waferID) {continue;}
744  //make a temporary to use within the loop and possibly erase - increment the main interator at the same time.
745  SCT_detElement_RIO_map::iterator currentExistingClusterIter = existingClusterIter++;
746 
747  const InDet::SCT_Cluster *existingCluster = (currentExistingClusterIter->second);
748  bool isNeighbour = this->NeighbouringClusters(potentialClusterRDOList, existingCluster);
749  if(isNeighbour)
750  {
751  //Merge the clusters
752  const std::vector<Identifier> &existingClusterRDOList = existingCluster->rdoList();
753  potentialClusterRDOList.insert(potentialClusterRDOList.end(), existingClusterRDOList.begin(), existingClusterRDOList.end() );
754  Amg::Vector2D existingClusterPosition(existingCluster->localPosition());
755  potentialClusterPosition = (potentialClusterPosition + existingClusterPosition)/2;
756  potentialClusterId = hitSiDetElement->identifierOfPosition(potentialClusterPosition);
757  //FIXME - also need to tidy up any associations to the deleted cluster in the truth container too.
758  SCT_DetElClusterMap.erase(currentExistingClusterIter);
759 
760 
761  //Store HepMcParticleLink connected to the cluster removed from the collection
762  std::pair<PRD_MultiTruthCollection::iterator,PRD_MultiTruthCollection::iterator> saved_hit = sctPrdTruth->equal_range(existingCluster->identify());
763  for (PRD_MultiTruthCollection::iterator this_hit = saved_hit.first; this_hit != saved_hit.second; ++this_hit)
764  {
765  hit_vector.push_back(this_hit->second);
766  }
767  //Delete all the occurency of the currentCluster from the multi map
768  if (saved_hit.first != saved_hit.second) sctPrdTruth->erase(existingCluster->identify());
769 
770  delete existingCluster;
771  ATH_MSG_VERBOSE("Merged two clusters.");
772  //break; // Should look for more than one possible merge.
773  }
774  }
775  ATH_MSG_INFO("After cluster merging there were " << SCT_DetElClusterMap.size() << " clusters in the SCT_DetElClusterMap.");
776  }
777  // check whether this is a trapezoid
778  const bool isTrapezoid(design->shape()==InDetDD::Trapezoid);
779  // prepare & create the siWidth
780  std::unique_ptr<InDet::SCT_Cluster> potentialClusterUniq = nullptr;
781  // Find length of strip at centre
782  const double clusterWidth(potentialClusterRDOList.size()*hitSiDetElement->phiPitch(potentialClusterPosition));
783  const std::pair<InDetDD::SiLocalPosition, InDetDD::SiLocalPosition> ends(design->endsOfStrip(potentialClusterPosition));
784  const double stripLength = std::abs(ends.first.xEta()-ends.second.xEta());
785  const InDet::SiWidth siWidth( Amg::Vector2D(int(potentialClusterRDOList.size()),1), Amg::Vector2D(clusterWidth,stripLength) );
786  // 2a) Cluster creation ------------------------------------
787  if (!m_clusterMaker.empty())
788  {
789  ATH_MSG_INFO("Using ClusterMakerTool to make cluster.");
790  // correct for the shift that will be applied in the cluster maker
791  // (only if surface charge emulation was switched off )
792  if (!m_sctEmulateSurfaceCharge && shift*shift > 0.)
793  {
794  potentialClusterPosition -= Amg::Vector2D(shift,0.);
795  }
796  // safe to compare m_sctTanLorentzAngleScalor with 1. since it is set not calculated
797  else if (m_sctTanLorentzAngleScalor != 1. && shift*shift > 0.)
798  {
799  // correct shift implied by the scaling of the Lorentz angle
800  const double newshift = 0.5*thickness*tanLorAng;
801  const double corr = ( shift - newshift );
802  potentialClusterPosition += Amg::Vector2D(corr,0.);
803  }
804  bool not_valid = false;
805  for (auto & i : potentialClusterRDOList)
806  {
807  if (!(i.is_valid()))
808  {
809  not_valid = true;
810  break;
811  }
812  }
813  if (not_valid)
814  {
815  continue;
816  }
817  potentialClusterUniq = std::make_unique<InDet::SCT_Cluster>(
818  m_clusterMaker->sctCluster(
819  potentialClusterId, potentialClusterPosition,
820  std::vector<Identifier>(potentialClusterRDOList), siWidth, hitSiDetElement,
822  }
823  else
824  {
825  ATH_MSG_INFO("Making cluster locally.");
826  // you need to correct for the lorentz drift -- only if surface charge emulation was switched on
827  const double appliedShift = m_sctEmulateSurfaceCharge ? m_sctTanLorentzAngleScalor*shift : (1.-m_sctTanLorentzAngleScalor)*shift;
828  const Amg::Vector2D lcorrectedPosition = Amg::Vector2D(potentialClusterPosition.x()+appliedShift,potentialClusterPosition.y());
829  AmgSymMatrix(2) mat;
830  mat.setIdentity();
831  mat(Trk::locX,Trk::locX) = (clusterWidth*clusterWidth)/12.;
832  mat(Trk::locY,Trk::locY) = (stripLength*stripLength)/12.;
833  // rotation for endcap SCT
834  if(isTrapezoid && m_sctRotateEC)
835  {
836  const double Sn = hitSiDetElement->sinStereoLocal(intersection);
837  const double Sn2 = Sn*Sn;
838  const double Cs2 = 1.-Sn2;
839  //double W = detElement->phiPitch(*clusterLocalPosition)/detElement->phiPitch();
840  //double V0 = mat(Trk::locX,Trk::locX)*W*W;
841  const double V0 = mat(Trk::locX,Trk::locX);
842  const double V1 = mat(Trk::locY,Trk::locY);
843  mat(Trk::locX,Trk::locX) = (Cs2*V0+Sn2*V1);
844  mat(Trk::locY,Trk::locX) = (Sn*sqrt(Cs2)*(V0-V1));
845  mat(Trk::locY,Trk::locY) = (Sn2*V0+Cs2*V1);
846  }
847 
848  // create a custom cluster
849  potentialClusterUniq = std::make_unique<InDet::SCT_Cluster>(
850  potentialClusterId, lcorrectedPosition,
851  std::vector<Identifier>(potentialClusterRDOList), siWidth, hitSiDetElement,
852  Amg::MatrixX(mat));
853  }
854 
855  //SCT_DetElClusterMap takes ownership of the ptr
856  const auto it =
857  SCT_DetElClusterMap.insert(SCT_detElement_RIO_map::value_type(
858  waferID, potentialClusterUniq.release()));
859 
860  //since we use this later
861  const InDet::SCT_Cluster* potentialCluster = it->second;
862 
863  // Build Truth info for current cluster
864  if (currentLink.isValid()) {
865  if (!HepMC::ignoreTruthLink(currentLink, m_vetoPileUpTruthLinks)) {
866  sctPrdTruth->insert(std::make_pair(potentialCluster->identify(), currentLink));
867  ATH_MSG_DEBUG("Truth map filled with cluster" << potentialCluster << " and link = " << currentLink);
868  }
869  }
870  else
871  {
872  ATH_MSG_DEBUG("Particle link NOT valid!! Truth map NOT filled with cluster" << potentialCluster << " and link = " << currentLink);
873  }
874 
875 
876  for(const HepMcParticleLink& p: hit_vector){
877  sctPrdTruth->insert(std::make_pair(potentialCluster->identify(), p ));
878  }
879 
880  hit_vector.clear();
881 
882 
883  } // end hit while
884 
885  (void) m_sctClusterMap->insert(SCT_DetElClusterMap.begin(), SCT_DetElClusterMap.end());
886  }
887  return StatusCode::SUCCESS;
888 }
889 
890 
892 {
894  sctClusterContainer = std::make_unique<InDet::SCT_ClusterContainer>(m_sct_ID->wafer_hash_max());
895  if(!sctClusterContainer.isValid()) {
896  ATH_MSG_FATAL( "[ --- ] Could not create SCT_ClusterContainer");
897  return StatusCode::FAILURE;
898  }
899  sctClusterContainer->cleanup();
900 
901  // --------------------------------------
902  // symlink the SCT Container
903  InDet::SiClusterContainer* symSiContainer=nullptr;
904  CHECK(evtStore()->symLink(sctClusterContainer.ptr(),symSiContainer));
905  ATH_MSG_DEBUG( "[ hitproc ] SCT_ClusterContainer symlinked to SiClusterContainer in StoreGate" );
906  // --------------------------------------
907 
908  // Get SCT_DetectorElementCollection
910  const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
911  if (elements==nullptr) {
912  ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
913  return StatusCode::FAILURE;
914  }
915 
916  SCT_detElement_RIO_map::iterator clusterMapGlobalIter = m_sctClusterMap->begin();
917  SCT_detElement_RIO_map::iterator endOfClusterMap = m_sctClusterMap->end();
918  for (; clusterMapGlobalIter != endOfClusterMap; clusterMapGlobalIter = m_sctClusterMap->upper_bound(clusterMapGlobalIter->first))
919  {
920  std::pair <SCT_detElement_RIO_map::iterator, SCT_detElement_RIO_map::iterator> range;
921  range = m_sctClusterMap->equal_range(clusterMapGlobalIter->first);
922  SCT_detElement_RIO_map::iterator firstDetElem = range.first;
923  const IdentifierHash waferID = firstDetElem->first;
924  const InDetDD::SiDetectorElement *detElement = elements->getDetectorElement(waferID);
925  InDet::SCT_ClusterCollection *clusterCollection = new InDet::SCT_ClusterCollection(waferID);
926  if (clusterCollection)
927  {
928  clusterCollection->setIdentifier(detElement->identify());
929  for ( SCT_detElement_RIO_map::iterator localClusterIter = range.first; localClusterIter != range.second; ++localClusterIter)
930  {
931  InDet::SCT_Cluster *sctCluster = localClusterIter->second;
932  sctCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
933  clusterCollection->push_back(sctCluster);
934  }
935  if (sctClusterContainer->addCollection(clusterCollection, clusterCollection->identifyHash()).isFailure())
936  {
937  ATH_MSG_WARNING( "Could not add collection to Identifiable container !" );
938  }
939  }
940  } // end for
941  m_sctClusterMap->clear();
942 
943  return StatusCode::SUCCESS;
944 }
945 
947  const InDetDD::SiDetectorElement& sidetel,
948  //const Trk::Surface& surface,
949  double localStartX, double localStartY,
950  double localEndX, double localEndY,
951  double slopeYX,
952  double slopeZX,
953  const Amg::Vector2D& stripCenter,
954  int direction)
955 {
956  double stepExitX = 0.;
957  double stepExitY = 0.;
958  double stepExitZ = 0.;
959  const double coef(1.);
960 
961  // probably needs to be changed to rect/trapezoid
962  if (sidetel.isBarrel())
963  {
964  // the exit position of the new strip
965  double xExitPosition = stripCenter.x()+direction*0.5*sidetel.phiPitch(stripCenter);
966  stepExitX = xExitPosition-localStartX;
967  stepExitY = stepExitX*slopeYX;
968  stepExitZ = stepExitX*slopeZX;
969  }
970  else
971  {
972  // the end position of this particular strip
973  std::pair<Amg::Vector3D,Amg::Vector3D> stripEndGlobal = sidetel.endsOfStrip(stripCenter);
974  Amg::Vector3D oneStripEndLocal = coef*stripEndGlobal.first;
975  Amg::Vector3D twoStripEndLocal = coef*stripEndGlobal.second;
976 
977  double oneStripPitch = sidetel.phiPitch(Amg::Vector2D(oneStripEndLocal.x(), oneStripEndLocal.y()));
978  double twoStripPitch = sidetel.phiPitch(Amg::Vector2D(twoStripEndLocal.x(), twoStripEndLocal.y()));
979  // now intersect track with border
980  Trk::LineIntersection2D intersectStripBorder(localStartX,localStartY,localEndX,localEndY,
981  oneStripEndLocal.x()+direction*0.5*oneStripPitch,oneStripEndLocal.y(),
982  twoStripEndLocal.x()+direction*0.5*twoStripPitch,twoStripEndLocal.y());
983  // the step in x
984  stepExitX = intersectStripBorder.interX - localStartX;
985  stepExitY = slopeYX*stepExitX;
986  stepExitZ = slopeZX*stepExitX;
987  }
988  return Amg::Vector3D(stepExitX,stepExitY,stepExitZ);
989 }
990 
991 bool SCT_FastDigitizationTool::NeighbouringClusters(const std::vector<Identifier>& potentialClusterRDOList, const InDet::SCT_Cluster *existingCluster) const
992 {
993  //---------------------------------------------------------------------------------
994  bool isNeighbour = false;
995  unsigned int countR(0);
996  const std::vector<Identifier> &existingClusterRDOList = existingCluster->rdoList();
997  std::vector<Identifier>::const_iterator potentialClusterRDOIter = potentialClusterRDOList.begin();
998  for ( ; potentialClusterRDOIter != potentialClusterRDOList.end(); ++potentialClusterRDOIter)
999  {
1000  ++countR;
1001  if (countR>100)
1002  {
1003  ATH_MSG_WARNING("Over 100 RDOs checked for the given cluster - bailing out!!");
1004  break;
1005  }
1006  std::vector<Identifier>::const_iterator existingClusterRDOIter = existingClusterRDOList.begin();
1007  for( ; existingClusterRDOIter != existingClusterRDOList.end(); ++existingClusterRDOIter)
1008  {
1009  if(std::abs(m_sct_ID->strip(*existingClusterRDOIter) - m_sct_ID->strip(*potentialClusterRDOIter)) < 2)
1010  {
1011  isNeighbour = true;
1012  break;
1013  }
1014  } // end of loop over RDOs in the current existing Cluster
1015  if (isNeighbour)
1016  {
1017  ATH_MSG_VERBOSE("The clusters are neighbours and can be merged.");
1018  break;
1019  }
1020  } // end of loop over RDOs in the potential cluster
1021  //---------------------------------------------------------------------------------
1022  return isNeighbour;
1023 }
1024 
1025 
1026 void SCT_FastDigitizationTool::Diffuse(HepGeom::Point3D<double>& localEntry, HepGeom::Point3D<double>& localExit, double shiftX, double shiftY ) {
1027 
1028  double localEntryX = localEntry.x();
1029  double localExitX = localExit.x();
1030 
1031  double signX = (localExitX - localEntryX) > 0 ? 1 : -1;
1032  localEntryX += shiftX * (-1) * signX;
1033  localExitX += shiftX * signX;
1034  localEntry.setX(localEntryX);
1035  localExit.setX(localExitX);
1036 
1037  double localEntryY = localEntry.y();
1038  double localExitY = localExit.y();
1039 
1040  double signY = (localExitY - localEntryY) > 0 ? 1 : -1;
1041  localEntryY += shiftY * (-1) * signY;
1042  localExitY += shiftY * signY;
1043 
1044  //Check the effect in the endcap
1045  localEntry.setY(localEntryY);
1046  localExit.setY(localExitY);
1047 
1048 }
InDetDD::SolidStateDetectorElementBase::hitLocalToLocal3D
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
Definition: SolidStateDetectorElementBase.cxx:117
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
InDetDD::SolidStateDetectorElementBase::identifierOfPosition
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
Definition: SolidStateDetectorElementBase.cxx:217
SCT_FastDigitizationTool::m_sctPrdTruthKey
SG::WriteHandleKey< PRD_MultiTruthCollection > m_sctPrdTruthKey
the PRD truth map for SCT measurements
Definition: SCT_FastDigitizationTool.h:130
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
SCT_FastDigitizationTool::m_DiffusionShiftY_endcap
DoubleProperty m_DiffusionShiftY_endcap
Definition: SCT_FastDigitizationTool.h:145
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
SCT_FastDigitizationTool::Diffuse
static void Diffuse(HepGeom::Point3D< double > &localEntry, HepGeom::Point3D< double > &localExit, double shiftX, double shiftY)
Definition: SCT_FastDigitizationTool.cxx:1026
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
SCT_FastDigitizationTool::mergeEvent
StatusCode mergeEvent(const EventContext &ctx)
Definition: SCT_FastDigitizationTool.cxx:205
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
SCT_FastDigitizationTool::m_SCTDetEleCollKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
Definition: SCT_FastDigitizationTool.h:131
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::locX
@ locX
Definition: ParamDefs.h:43
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
Surface.h
SCT_ModuleSideDesign.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SCT_FastDigitizationTool::m_sctAnalogStripClustering
BooleanProperty m_sctAnalogStripClustering
not being done in ATLAS: analog strip clustering
Definition: SCT_FastDigitizationTool.h:137
InDetDD::SCT_ModuleSideDesign
Definition: SCT_ModuleSideDesign.h:40
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
InDetDD::DetectorDesign::shape
virtual DetectorShape shape() const
Shape of element.
Definition: DetectorDesign.cxx:96
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:53
LineIntersection2D.h
SCT_FastDigitizationTool::stepToStripBorder
static Amg::Vector3D stepToStripBorder(const InDetDD::SiDetectorElement &sidetel, double localStartX, double localStartY, double localEndX, double localEndY, double slopeYX, double slopeZX, const Amg::Vector2D &stripCenter, int direction)
Definition: SCT_FastDigitizationTool.cxx:946
AtlasHitsVector
Definition: AtlasHitsVector.h:33
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
skel.it
it
Definition: skel.GENtoEVGEN.py:423
SCT_FastDigitizationTool::m_mergeSvc
ServiceHandle< PileUpMergeSvc > m_mergeSvc
PileUp Merge service.
Definition: SCT_FastDigitizationTool.h:114
InDetDD::SolidStateDetectorElementBase::surface
Trk::Surface & surface()
Element Surface.
Trk::PrepRawData::rdoList
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
SCT_ForwardModuleSideDesign.h
PileUpTimeEventIndex::index
index_type index() const
the index of the component event in PileUpEventInfo
Definition: PileUpTimeEventIndex.cxx:76
InDetDD::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition: SiCellId.h:122
SCT_FastDigitizationTool::m_thpcsi
TimedHitCollection< SiHit > * m_thpcsi
Definition: SCT_FastDigitizationTool.h:121
SCT_FastDigitizationTool::createAndStoreRIOs
StatusCode createAndStoreRIOs(const EventContext &ctx)
Definition: SCT_FastDigitizationTool.cxx:891
TimedHitPtr< SiHit >
SCT_FastDigitizationTool::m_inputObjectName
StringProperty m_inputObjectName
Definition: SCT_FastDigitizationTool.h:109
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
HepMC::ignoreTruthLink
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
Definition: MagicNumbers.h:296
SCT_FastDigitizationTool::m_lorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Definition: SCT_FastDigitizationTool.h:124
SCT_FastDigitizationTool::prepareEvent
StatusCode prepareEvent(const EventContext &ctx, unsigned int)
Definition: SCT_FastDigitizationTool.cxx:104
SCT_FastDigitizationTool::m_sctSmearLandau
BooleanProperty m_sctSmearLandau
if true : landau else: gauss
Definition: SCT_FastDigitizationTool.h:134
TimedHitCollection::nextDetectorElement
bool nextDetectorElement(const_iterator &b, const_iterator &e)
sets an iterator range with the hits of current detector element returns a bool when done
SCT_Cluster.h
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
InDetDD::SCT_ModuleSideDesign::cells
int cells() const
number of readout stips within module side:
Definition: SCT_ModuleSideDesign.h:228
Identifier::is_valid
bool is_valid() const
Check if id is in a valid state.
GenParticle.h
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
ReadCondHandle.h
PileUpToolBase::m_vetoPileUpTruthLinks
Gaudi::Property< int > m_vetoPileUpTruthLinks
Definition: PileUpToolBase.h:58
SCT_CalibAlgs::lastStrip
@ lastStrip
Definition: SCT_CalibNumbers.h:10
PileUpMergeSvc::TimedList::type
std::list< value_t > type
type of the collection of timed data object
Definition: PileUpMergeSvc.h:75
Trk::LineIntersection2D::interX
double interX
Definition: LineIntersection2D.h:35
InDetDD::SolidStateDetectorElementBase::hitDepthDirection
double hitDepthDirection() const
Directions of hit depth,phi,eta axes relative to reconstruction local position axes (LocalPosition).
SurfaceBounds.h
InDetDD::SiDetectorElement::phiPitch
double phiPitch() const
Pitch (inline methods)
InDetDD::SiDetectorElement::cellIdFromIdentifier
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
Definition: SiDetectorElement.cxx:120
SCT_FastDigitizationTool.h
Digitize the SCT using an implementation of IPileUpTool.
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadCondHandle::retrieve
const_pointer_type retrieve()
Definition: ReadCondHandle.h:161
TimedHitCollection::insert
void insert(const PileUpTimeEventIndex &timeEventIndex, const AtlasHitsVector< HIT > *inputCollection)
SCT_FastDigitizationTool::m_sctClusterContainerKey
SG::WriteHandleKey< InDet::SCT_ClusterContainer > m_sctClusterContainerKey
the SCT_ClusterContainer
Definition: SCT_FastDigitizationTool.h:129
SCT_FastDigitizationTool::m_sctSmearPathLength
DoubleProperty m_sctSmearPathLength
the 2.
Definition: SCT_FastDigitizationTool.h:133
ClusterMakerTool.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
InDetDD::SolidStateDetectorElementBase::thickness
double thickness() const
SCT_FastDigitizationTool::m_sctRotateEC
BooleanProperty m_sctRotateEC
Definition: SCT_FastDigitizationTool.h:139
Trk::PrepRawData::setHashAndIndex
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SCT_FastDigitizationTool::initialize
virtual StatusCode initialize()
Called before processing physics events.
Definition: SCT_FastDigitizationTool.cxx:65
SCT_FastDigitizationTool::processBunchXing
StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents)
Definition: SCT_FastDigitizationTool.cxx:114
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
SCT_FastDigitizationTool::m_mergeCluster
bool m_mergeCluster
enable the merging of neighbour SCT clusters >
Definition: SCT_FastDigitizationTool.h:141
test_pyathena.parent
parent
Definition: test_pyathena.py:15
SCT_FastDigitizationTool::m_DiffusionShiftY_barrel
DoubleProperty m_DiffusionShiftY_barrel
Definition: SCT_FastDigitizationTool.h:143
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SCT_FastDigitizationTool::processAllSubEvents
StatusCode processAllSubEvents(const EventContext &ctx)
Definition: SCT_FastDigitizationTool.cxx:155
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
SCT_ID::wafer_hash
IdentifierHash wafer_hash(const Identifier &wafer_id) const
wafer hash from id - optimized
Definition: SCT_ID.h:492
python.SystemOfUnits.micrometer
int micrometer
Definition: SystemOfUnits.py:71
SCT_FastDigitizationTool::digitize
StatusCode digitize(const EventContext &ctx, TimedHitCollection< SiHit > &thpcsi)
Definition: SCT_FastDigitizationTool.cxx:226
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
SCT_FastDigitizationTool::m_randomEngineName
StringProperty m_randomEngineName
Name of the random number stream.
Definition: SCT_FastDigitizationTool.h:119
InDet::SCT_Cluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/SCT_Cluster.h:34
Trk::SurfaceBounds::insideLoc2
virtual bool insideLoc2(const Amg::Vector2D &locpo, double tol2=0.) const =0
Extend the interface to for single inside Loc 1 / Loc2 tests.
SCT_FastDigitizationTool::m_HardScatterSplittingSkipper
bool m_HardScatterSplittingSkipper
Definition: SCT_FastDigitizationTool.h:116
SCT_FastDigitizationTool::m_sctEmulateSurfaceCharge
BooleanProperty m_sctEmulateSurfaceCharge
emulate the surface charge
Definition: SCT_FastDigitizationTool.h:135
PileUpToolBase
Definition: PileUpToolBase.h:18
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
InDetDD::SiDetectorElement::endsOfStrip
std::pair< Amg::Vector3D, Amg::Vector3D > endsOfStrip(const Amg::Vector2D &position) const
Special method for SCT to retrieve the two ends of a "strip" Returned coordinates are in global frame...
Definition: SiDetectorElement.cxx:339
SG::WriteHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
SCT_FastDigitizationTool::m_clusterMaker
PublicToolHandle< InDet::ClusterMakerTool > m_clusterMaker
Definition: SCT_FastDigitizationTool.h:123
SCT_FastDigitizationTool::SCT_FastDigitizationTool
SCT_FastDigitizationTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: SCT_FastDigitizationTool.cxx:54
Trk::Surface::bounds
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
SCT_ID::wafer_hash_max
size_type wafer_hash_max(void) const
Definition: SCT_ID.cxx:639
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
PileUpTimeEventIndex::time
time_type time() const
bunch xing time in ns
Definition: PileUpTimeEventIndex.cxx:71
Trk::PrepRawData::localPosition
const Amg::Vector2D & localPosition() const
return the local position reference
SiCluster.h
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDetDD::SiDetectorElement::isBarrel
bool isBarrel() const
InDet::SiClusterContainer
Trk::PrepRawDataContainer< SiClusterCollection > SiClusterContainer
Definition: SiClusterContainer.h:26
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::LineIntersection2D
Definition: LineIntersection2D.h:32
SiDetectorElement.h
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
RNGWrapper.h
InDetDD::SiCellId
Definition: SiCellId.h:29
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
SiHitCollection
AtlasHitsVector< SiHit > SiHitCollection
Definition: SiHitCollection.h:14
SiClusterContainer.h
InDetDD::SolidStateDetectorElementBase::rawLocalPositionOfCell
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
Definition: SolidStateDetectorElementBase.cxx:230
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
SCT_BarrelModuleSideDesign.h
Trk::LineIntersection2D::interY
double interY
Definition: LineIntersection2D.h:36
SCT_FastDigitizationTool::m_HardScatterSplittingMode
IntegerProperty m_HardScatterSplittingMode
Process all SiHit or just those from signal or background events.
Definition: SCT_FastDigitizationTool.h:115
TimedHitPtr::eventId
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition: TimedHitPtr.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
SCT_ID::strip
int strip(const Identifier &id) const
Definition: SCT_ID.h:764
PileUpMergeSvc.h
the preferred mechanism to access information from the different event stores in a pileup job.
InDetSimDataCollection.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DeMoScan.first
bool first
Definition: DeMoScan.py:534
SCT_FastDigitizationTool::m_sctClusterMap
SCT_detElement_RIO_map * m_sctClusterMap
Definition: SCT_FastDigitizationTool.h:127
InDetDD::SiDetectorElement::sinStereoLocal
double sinStereoLocal(const Amg::Vector2D &localPos) const
Angle of strip in local frame with respect to the etaAxis.
Definition: SiDetectorElement.cxx:288
InDet::SiWidth
Definition: SiWidth.h:25
AtlasHitsVector::size
size_type size() const
Definition: AtlasHitsVector.h:143
SubEventIterator
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition: IPileUpTool.h:22
SCT_FastDigitizationTool::m_siHitCollList
std::vector< SiHitCollection * > m_siHitCollList
name of the sub event hit collections.
Definition: SCT_FastDigitizationTool.h:111
InDetDD::SolidStateDetectorElementBase::length
double length() const
Length in eta direction (z - barrel, r - endcap)
SCT_ID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side) const
For a single side of module.
Definition: SCT_ID.h:464
IdentifierHash
Definition: IdentifierHash.h:38
SCT_FastDigitizationTool::SCT_detElement_RIO_map
std::multimap< IdentifierHash, InDet::SCT_Cluster * > SCT_detElement_RIO_map
Definition: SCT_FastDigitizationTool.h:126
SiCellId.h
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
InDet::SCT_ClusterCollection
Trk::PrepRawDataCollection< SCT_Cluster > SCT_ClusterCollection
Definition: SCT_ClusterCollection.h:26
PileUpTimeEventIndex
a struct encapsulating the identifier of a pile-up event
Definition: PileUpTimeEventIndex.h:12
PileUpTimeEventIndex::type
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
Definition: PileUpTimeEventIndex.cxx:81
InDetDD::SCT_ModuleSideDesign::endsOfStrip
virtual std::pair< SiLocalPosition, SiLocalPosition > endsOfStrip(const SiLocalPosition &position) const override=0
give the ends of strips
SCT_FastDigitizationTool::m_sctMinimalPathCut
DoubleProperty m_sctMinimalPathCut
the 1.
Definition: SCT_FastDigitizationTool.h:146
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
SCT_FastDigitizationTool::NeighbouringClusters
bool NeighbouringClusters(const std::vector< Identifier > &potentialClusterRDOList, const InDet::SCT_Cluster *existingCluster) const
Definition: SCT_FastDigitizationTool.cxx:991
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:25
TimedHitCollection< SiHit >
SCT_FastDigitizationTool::m_DiffusionShiftX_endcap
DoubleProperty m_DiffusionShiftX_endcap
Definition: SCT_FastDigitizationTool.h:144
SiDetectorDesign.h
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
WriteCalibToCool.coef
coef
Definition: WriteCalibToCool.py:582
SCT_FastDigitizationTool::m_sct_ID
const SCT_ID * m_sct_ID
Handle to the ID helper.
Definition: SCT_FastDigitizationTool.h:113
SCT_FastDigitizationTool::m_sctTanLorentzAngleScalor
DoubleProperty m_sctTanLorentzAngleScalor
scale the lorentz angle effect
Definition: SCT_FastDigitizationTool.h:136
SCT_FastDigitizationTool::m_DiffusionShiftX_barrel
DoubleProperty m_DiffusionShiftX_barrel
Definition: SCT_FastDigitizationTool.h:142
SCT_FastDigitizationTool::m_sctErrorStrategy
IntegerProperty m_sctErrorStrategy
error strategy for the ClusterMaker
Definition: SCT_FastDigitizationTool.h:138
InDetDD::Trapezoid
@ Trapezoid
Definition: DetectorDesign.h:42
fitman.k
k
Definition: fitman.py:528
SCT_FastDigitizationTool::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
Definition: SCT_FastDigitizationTool.h:118
SiHitCollection.h