ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_FastDigitizationTool Class Reference

#include <SCT_FastDigitizationTool.h>

Inheritance diagram for SCT_FastDigitizationTool:

Public Member Functions

 SCT_FastDigitizationTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize ()
 Called before processing physics events.
StatusCode prepareEvent (const EventContext &ctx, unsigned int)
StatusCode processBunchXing (int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents)
StatusCode mergeEvent (const EventContext &ctx)
StatusCode processAllSubEvents (const EventContext &ctx)
StatusCode createAndStoreRIOs (const EventContext &ctx)

Private Types

typedef std::multimap< IdentifierHash, InDet::SCT_Cluster * > SCT_detElement_RIO_map

Private Member Functions

StatusCode digitize (const EventContext &ctx, TimedHitCollection< SiHit > &thpcsi)
bool NeighbouringClusters (const std::vector< Identifier > &potentialClusterRDOList, const InDet::SCT_Cluster *existingCluster) const

Static Private Member Functions

static void Diffuse (HepGeom::Point3D< double > &localEntry, HepGeom::Point3D< double > &localExit, double shiftX, double shiftY)
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)

Private Attributes

StringProperty m_inputObjectName {this, "InputObjectName", "SCT_Hits", "Input Object name"}
std::vector< SiHitCollection * > m_siHitCollList
 name of the sub event hit collections.
const SCT_IDm_sct_ID {}
 Handle to the ID helper.
ServiceHandle< PileUpMergeSvcm_mergeSvc {this, "MergeSvc", "PileUpMergeSvc", "Merge service"}
 PileUp Merge service.
IntegerProperty m_HardScatterSplittingMode {this, "HardScatterSplittingMode", 0, "Control pileup & signal splitting"}
 Process all SiHit or just those from signal or background events.
bool m_HardScatterSplittingSkipper {false}
ServiceHandle< IAthRNGSvcm_rndmSvc {this, "RndmSvc", "AthRNGSvc", ""}
 Random number service.
StringProperty m_randomEngineName {this, "RndmEngine", "FastSCT_Digitization"}
 Name of the random number stream.
TimedHitCollection< SiHit > * m_thpcsi {}
PublicToolHandle< InDet::ClusterMakerToolm_clusterMaker {this, "ClusterMaker", "InDet::ClusterMakerTool"}
ToolHandle< ISiLorentzAngleToolm_lorentzAngleTool {this, "LorentzAngleTool", "SiLorentzAngleTool/SCTLorentzAngleTool", "Tool to retreive Lorentz angle"}
SCT_detElement_RIO_mapm_sctClusterMap {}
SG::WriteHandleKey< InDet::SCT_ClusterContainer > m_sctClusterContainerKey {this, "SCT_ClusterContainerName", "SCT_Clusters"}
 the SCT_ClusterContainer
SG::WriteHandleKey< PRD_MultiTruthCollectionm_sctPrdTruthKey {this, "TruthNameSCT", "PRD_MultiTruthSCT"}
 the PRD truth map for SCT measurements
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollectionm_SCTDetEleCollKey {this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"}
DoubleProperty m_sctSmearPathLength {this, "SCT_SmearPathSigma", 0.01}
 the 2.
BooleanProperty m_sctSmearLandau {this, "SCT_SmearLandau", true}
 if true : landau else: gauss
BooleanProperty m_sctEmulateSurfaceCharge {this, "EmulateSurfaceCharge", true}
 emulate the surface charge
DoubleProperty m_sctTanLorentzAngleScalor {this, "SCT_ScaleTanLorentzAngle", 1.}
 scale the lorentz angle effect
BooleanProperty m_sctAnalogStripClustering {this, "SCT_AnalogClustering", false}
 not being done in ATLAS: analog strip clustering
IntegerProperty m_sctErrorStrategy {this, "SCT_ErrorStrategy", 2}
 error strategy for the ClusterMaker
BooleanProperty m_sctRotateEC {this, "SCT_RotateEndcapClusters", true}
bool m_mergeCluster {true}
 enable the merging of neighbour SCT clusters >
DoubleProperty m_DiffusionShiftX_barrel {this, "DiffusionShiftX_barrel",4 }
DoubleProperty m_DiffusionShiftY_barrel {this, "DiffusionShiftY_barrel", 4}
DoubleProperty m_DiffusionShiftX_endcap {this, "DiffusionShiftX_endcap", 15}
DoubleProperty m_DiffusionShiftY_endcap {this, "DiffusionShiftY_endcap", 15}
DoubleProperty m_sctMinimalPathCut {this, "SCT_MinimalPathLength", 90.}
 the 1.

structors and AlgTool implementation

virtual bool toProcess (int bunchXing) const override
 the method this base class helps implementing
virtual bool filterPassed () const override
 dummy implementation of passing filter
virtual void resetFilter () override
 dummy implementation of filter reset
Gaudi::Property< int > m_firstXing
Gaudi::Property< int > m_lastXing
Gaudi::Property< int > m_vetoPileUpTruthLinks
bool m_filterPassed {true}

Detailed Description

Definition at line 82 of file SCT_FastDigitizationTool.h.

Member Typedef Documentation

◆ SCT_detElement_RIO_map

Constructor & Destructor Documentation

◆ SCT_FastDigitizationTool()

SCT_FastDigitizationTool::SCT_FastDigitizationTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 54 of file SCT_FastDigitizationTool.cxx.

56 :
57
58 PileUpToolBase(type, name, parent)
59{
60}
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)

Member Function Documentation

◆ createAndStoreRIOs()

StatusCode SCT_FastDigitizationTool::createAndStoreRIOs ( const EventContext & ctx)

Definition at line 895 of file SCT_FastDigitizationTool.cxx.

896{
897 SG::WriteHandle<InDet::SCT_ClusterContainer> sctClusterContainer(m_sctClusterContainerKey, ctx);
898 sctClusterContainer = std::make_unique<InDet::SCT_ClusterContainer>(m_sct_ID->wafer_hash_max());
899 if(!sctClusterContainer.isValid()) {
900 ATH_MSG_FATAL( "[ --- ] Could not create SCT_ClusterContainer");
901 return StatusCode::FAILURE;
902 }
903 sctClusterContainer->cleanup();
904
905 // --------------------------------------
906 // symlink the SCT Container
907 InDet::SiClusterContainer* symSiContainer=nullptr;
908 CHECK(evtStore()->symLink(sctClusterContainer.ptr(),symSiContainer));
909 ATH_MSG_DEBUG( "[ hitproc ] SCT_ClusterContainer symlinked to SiClusterContainer in StoreGate" );
910 // --------------------------------------
911
912 // Get SCT_DetectorElementCollection
913 SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
914 const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
915 if (elements==nullptr) {
916 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
917 return StatusCode::FAILURE;
918 }
919
920 SCT_detElement_RIO_map::iterator clusterMapGlobalIter = m_sctClusterMap->begin();
921 SCT_detElement_RIO_map::iterator endOfClusterMap = m_sctClusterMap->end();
922 for (; clusterMapGlobalIter != endOfClusterMap; clusterMapGlobalIter = m_sctClusterMap->upper_bound(clusterMapGlobalIter->first))
923 {
924 std::pair <SCT_detElement_RIO_map::iterator, SCT_detElement_RIO_map::iterator> range;
925 range = m_sctClusterMap->equal_range(clusterMapGlobalIter->first);
926 SCT_detElement_RIO_map::iterator firstDetElem = range.first;
927 const IdentifierHash waferID = firstDetElem->first;
928 const InDetDD::SiDetectorElement *detElement = elements->getDetectorElement(waferID);
929 InDet::SCT_ClusterCollection *clusterCollection = new InDet::SCT_ClusterCollection(waferID);
930 if (clusterCollection)
931 {
932 clusterCollection->setIdentifier(detElement->identify());
933 for ( SCT_detElement_RIO_map::iterator localClusterIter = range.first; localClusterIter != range.second; ++localClusterIter)
934 {
935 InDet::SCT_Cluster *sctCluster = localClusterIter->second;
936 sctCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
937 clusterCollection->push_back(sctCluster);
938 }
939 if (sctClusterContainer->addCollection(clusterCollection, clusterCollection->identifyHash()).isFailure())
940 {
941 ATH_MSG_WARNING( "Could not add collection to Identifiable container !" );
942 }
943 }
944 } // end for
945 m_sctClusterMap->clear();
946
947 return StatusCode::SUCCESS;
948}
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
virtual Identifier identify() const override final
identifier of this detector element (inline)
Trk::PrepRawDataCollection< SCT_Cluster > SCT_ClusterCollection
Trk::PrepRawDataContainer< SiClusterCollection > SiClusterContainer
const SCT_ID * m_sct_ID
Handle to the ID helper.
SCT_detElement_RIO_map * m_sctClusterMap
SG::WriteHandleKey< InDet::SCT_ClusterContainer > m_sctClusterContainerKey
the SCT_ClusterContainer
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...

◆ Diffuse()

void SCT_FastDigitizationTool::Diffuse ( HepGeom::Point3D< double > & localEntry,
HepGeom::Point3D< double > & localExit,
double shiftX,
double shiftY )
staticprivate

Definition at line 1030 of file SCT_FastDigitizationTool.cxx.

1030 {
1031
1032 double localEntryX = localEntry.x();
1033 double localExitX = localExit.x();
1034
1035 double signX = (localExitX - localEntryX) > 0 ? 1 : -1;
1036 localEntryX += shiftX * (-1) * signX;
1037 localExitX += shiftX * signX;
1038 localEntry.setX(localEntryX);
1039 localExit.setX(localExitX);
1040
1041 double localEntryY = localEntry.y();
1042 double localExitY = localExit.y();
1043
1044 double signY = (localExitY - localEntryY) > 0 ? 1 : -1;
1045 localEntryY += shiftY * (-1) * signY;
1046 localExitY += shiftY * signY;
1047
1048 //Check the effect in the endcap
1049 localEntry.setY(localEntryY);
1050 localExit.setY(localExitY);
1051
1052}

◆ digitize()

StatusCode SCT_FastDigitizationTool::digitize ( const EventContext & ctx,
TimedHitCollection< SiHit > & thpcsi )
private

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

< @TODO CHECK

Definition at line 226 of file SCT_FastDigitizationTool.cxx.

228{
229 // truth info
230 SG::WriteHandle< PRD_MultiTruthCollection > sctPrdTruth(m_sctPrdTruthKey, ctx);
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
245 SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
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, ctx);
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, ctx);
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 if (totalWeight == 0.)[[unlikely]]{
726 ATH_MSG_WARNING("totalWeight is zero.");
727 continue;
728 }
729 potentialClusterPosition *= 1./totalWeight;
730 /*const */Identifier potentialClusterId = hitSiDetElement->identifierOfPosition(potentialClusterPosition);
731 if (!potentialClusterId.is_valid()) {continue;}
732
733 const IdentifierHash waferID = m_sct_ID->wafer_hash(hitSiDetElement->identify());
734
735 // merging clusters
736 if(m_mergeCluster){
737 unsigned int countC(0);
738 ATH_MSG_INFO("Before cluster merging there were " << SCT_DetElClusterMap.size() << " clusters in the SCT_DetElClusterMap.");
739 for(SCT_detElement_RIO_map::iterator existingClusterIter = SCT_DetElClusterMap.begin(); existingClusterIter != SCT_DetElClusterMap.end();)
740 {
741 ++countC;
742 if (countC>100)
743 {
744 ATH_MSG_WARNING("Over 100 clusters checked for merging - bailing out!!");
745 break;
746 }
747 if (m_sct_ID->wafer_hash(((existingClusterIter->second)->detectorElement())->identify()) != waferID) {continue;}
748 //make a temporary to use within the loop and possibly erase - increment the main interator at the same time.
749 SCT_detElement_RIO_map::iterator currentExistingClusterIter = existingClusterIter++;
750
751 const InDet::SCT_Cluster *existingCluster = (currentExistingClusterIter->second);
752 bool isNeighbour = this->NeighbouringClusters(potentialClusterRDOList, existingCluster);
753 if(isNeighbour)
754 {
755 //Merge the clusters
756 const std::vector<Identifier> &existingClusterRDOList = existingCluster->rdoList();
757 potentialClusterRDOList.insert(potentialClusterRDOList.end(), existingClusterRDOList.begin(), existingClusterRDOList.end() );
758 Amg::Vector2D existingClusterPosition(existingCluster->localPosition());
759 potentialClusterPosition = (potentialClusterPosition + existingClusterPosition)/2;
760 potentialClusterId = hitSiDetElement->identifierOfPosition(potentialClusterPosition);
761 //FIXME - also need to tidy up any associations to the deleted cluster in the truth container too.
762 SCT_DetElClusterMap.erase(currentExistingClusterIter);
763
764
765 //Store HepMcParticleLink connected to the cluster removed from the collection
766 std::pair<PRD_MultiTruthCollection::iterator,PRD_MultiTruthCollection::iterator> saved_hit = sctPrdTruth->equal_range(existingCluster->identify());
767 for (PRD_MultiTruthCollection::iterator this_hit = saved_hit.first; this_hit != saved_hit.second; ++this_hit)
768 {
769 hit_vector.push_back(this_hit->second);
770 }
771 //Delete all the occurency of the currentCluster from the multi map
772 if (saved_hit.first != saved_hit.second) sctPrdTruth->erase(existingCluster->identify());
773
774 delete existingCluster;
775 ATH_MSG_VERBOSE("Merged two clusters.");
776 //break; // Should look for more than one possible merge.
777 }
778 }
779 ATH_MSG_INFO("After cluster merging there were " << SCT_DetElClusterMap.size() << " clusters in the SCT_DetElClusterMap.");
780 }
781 // check whether this is a trapezoid
782 const bool isTrapezoid(design->shape()==InDetDD::Trapezoid);
783 // prepare & create the siWidth
784 std::unique_ptr<InDet::SCT_Cluster> potentialClusterUniq = nullptr;
785 // Find length of strip at centre
786 const double clusterWidth(potentialClusterRDOList.size()*hitSiDetElement->phiPitch(potentialClusterPosition));
787 const std::pair<InDetDD::SiLocalPosition, InDetDD::SiLocalPosition> ends(design->endsOfStrip(potentialClusterPosition));
788 const double stripLength = std::abs(ends.first.xEta()-ends.second.xEta());
789 const InDet::SiWidth siWidth( Amg::Vector2D(int(potentialClusterRDOList.size()),1), Amg::Vector2D(clusterWidth,stripLength) );
790 // 2a) Cluster creation ------------------------------------
791 if (!m_clusterMaker.empty())
792 {
793 ATH_MSG_INFO("Using ClusterMakerTool to make cluster.");
794 // correct for the shift that will be applied in the cluster maker
795 // (only if surface charge emulation was switched off )
796 if (!m_sctEmulateSurfaceCharge && shift*shift > 0.)
797 {
798 potentialClusterPosition -= Amg::Vector2D(shift,0.);
799 }
800 // safe to compare m_sctTanLorentzAngleScalor with 1. since it is set not calculated
801 else if (m_sctTanLorentzAngleScalor != 1. && shift*shift > 0.)
802 {
803 // correct shift implied by the scaling of the Lorentz angle
804 const double newshift = 0.5*thickness*tanLorAng;
805 const double corr = ( shift - newshift );
806 potentialClusterPosition += Amg::Vector2D(corr,0.);
807 }
808 bool not_valid = false;
809 for (auto & i : potentialClusterRDOList)
810 {
811 if (!(i.is_valid()))
812 {
813 not_valid = true;
814 break;
815 }
816 }
817 if (not_valid)
818 {
819 continue;
820 }
821 potentialClusterUniq = std::make_unique<InDet::SCT_Cluster>(
822 m_clusterMaker->sctCluster(
823 potentialClusterId, potentialClusterPosition,
824 std::move(potentialClusterRDOList), siWidth, hitSiDetElement,
826 }
827 else
828 {
829 ATH_MSG_INFO("Making cluster locally.");
830 // you need to correct for the lorentz drift -- only if surface charge emulation was switched on
832 const Amg::Vector2D lcorrectedPosition = Amg::Vector2D(potentialClusterPosition.x()+appliedShift,potentialClusterPosition.y());
833 AmgSymMatrix(2) mat;
834 mat.setIdentity();
835 mat(Trk::locX,Trk::locX) = (clusterWidth*clusterWidth)/12.;
836 mat(Trk::locY,Trk::locY) = (stripLength*stripLength)/12.;
837 // rotation for endcap SCT
838 if(isTrapezoid && m_sctRotateEC)
839 {
840 const double Sn = hitSiDetElement->sinStereoLocal(intersection);
841 const double Sn2 = Sn*Sn;
842 const double Cs2 = 1.-Sn2;
843 //double W = detElement->phiPitch(*clusterLocalPosition)/detElement->phiPitch();
844 //double V0 = mat(Trk::locX,Trk::locX)*W*W;
845 const double V0 = mat(Trk::locX,Trk::locX);
846 const double V1 = mat(Trk::locY,Trk::locY);
847 mat(Trk::locX,Trk::locX) = (Cs2*V0+Sn2*V1);
848 mat(Trk::locY,Trk::locX) = (Sn*sqrt(Cs2)*(V0-V1));
849 mat(Trk::locY,Trk::locY) = (Sn2*V0+Cs2*V1);
850 }
851
852 // create a custom cluster
853 potentialClusterUniq = std::make_unique<InDet::SCT_Cluster>(
854 potentialClusterId, lcorrectedPosition,
855 std::vector<Identifier>(potentialClusterRDOList), siWidth, hitSiDetElement,
856 Amg::MatrixX(mat));
857 }
858
859 //SCT_DetElClusterMap takes ownership of the ptr
860 const auto it =
861 SCT_DetElClusterMap.insert(SCT_detElement_RIO_map::value_type(
862 waferID, potentialClusterUniq.release()));
863
864 //since we use this later
865 const InDet::SCT_Cluster* potentialCluster = it->second;
866
867 // Build Truth info for current cluster
868 if (currentLink.isValid()) {
870 sctPrdTruth->insert(std::make_pair(potentialCluster->identify(), currentLink));
871 ATH_MSG_DEBUG("Truth map filled with cluster" << potentialCluster << " and link = " << currentLink);
872 }
873 }
874 else
875 {
876 ATH_MSG_DEBUG("Particle link NOT valid!! Truth map NOT filled with cluster" << potentialCluster << " and link = " << currentLink);
877 }
878
879
880 for(const HepMcParticleLink& p: hit_vector){
881 sctPrdTruth->insert(std::make_pair(potentialCluster->identify(), p ));
882 }
883
884 hit_vector.clear();
885
886
887 } // end hit while
888
889 (void) m_sctClusterMap->insert(SCT_DetElClusterMap.begin(), SCT_DetElClusterMap.end());
890 }
891 return StatusCode::SUCCESS;
892}
Scalar mag() const
mag method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define AmgSymMatrix(dim)
if(pathvar)
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:154
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:108
bool is_valid() const
Check if id is in a valid state.
virtual DetectorShape shape() const
Shape of element.
int cells() const
number of readout stips within module side:
virtual std::pair< SiLocalPosition, SiLocalPosition > endsOfStrip(const SiLocalPosition &position) const override=0
give the ends of strips
int phiIndex() const
Get phi index. Equivalent to strip().
Definition SiCellId.h:122
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
double phiPitch() const
Pitch (inline methods).
double sinStereoLocal(const Amg::Vector2D &localPos) const
Angle of strip in local frame with respect to the etaAxis.
double length() const
Length in eta direction (z - barrel, r - endcap).
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
double hitDepthDirection() const
Directions of hit depth,phi,eta axes relative to reconstruction local position axes (LocalPosition).
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift).
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
Trk::Surface & surface()
Element Surface.
Gaudi::Property< int > m_vetoPileUpTruthLinks
BooleanProperty m_sctSmearLandau
if true : landau else: gauss
SG::WriteHandleKey< PRD_MultiTruthCollection > m_sctPrdTruthKey
the PRD truth map for SCT measurements
StringProperty m_randomEngineName
Name of the random number stream.
bool m_mergeCluster
enable the merging of neighbour SCT clusters >
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
DoubleProperty m_sctSmearPathLength
the 2.
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)
IntegerProperty m_sctErrorStrategy
error strategy for the ClusterMaker
PublicToolHandle< InDet::ClusterMakerTool > m_clusterMaker
std::multimap< IdentifierHash, InDet::SCT_Cluster * > SCT_detElement_RIO_map
bool NeighbouringClusters(const std::vector< Identifier > &potentialClusterRDOList, const InDet::SCT_Cluster *existingCluster) const
DoubleProperty m_sctMinimalPathCut
the 1.
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
DoubleProperty m_sctTanLorentzAngleScalor
scale the lorentz angle effect
BooleanProperty m_sctEmulateSurfaceCharge
emulate the surface charge
static void Diffuse(HepGeom::Point3D< double > &localEntry, HepGeom::Point3D< double > &localExit, double shiftX, double shiftY)
BooleanProperty m_sctAnalogStripClustering
not being done in ATLAS: analog strip clustering
bool nextDetectorElement(const_iterator &b, const_iterator &e)
sets an iterator range with the hits of current detector element returns a bool when done
TimedVector::const_iterator const_iterator
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
virtual bool insideLoc2(const Amg::Vector2D &locpo, double tol2=0.) const =0
Extend the interface to for single inside Loc 1 / Loc2 tests.
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the elements of the container.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
#define unlikely(x)

◆ filterPassed()

virtual bool PileUpToolBase::filterPassed ( ) const
inlineoverridevirtualinherited

dummy implementation of passing filter

Definition at line 49 of file PileUpToolBase.h.

49{ return m_filterPassed; }

◆ initialize()

StatusCode SCT_FastDigitizationTool::initialize ( )
virtual

Called before processing physics events.

Reimplemented from PileUpToolBase.

Definition at line 65 of file SCT_FastDigitizationTool.cxx.

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 }
83 ATH_CHECK(m_sctPrdTruthKey.initialize());
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
96 m_sctMinimalPathCut = m_sctMinimalPathCut * Gaudi::Units::micrometer;
97
98 // Initialize ReadCondHandleKey
99 ATH_CHECK(m_SCTDetEleCollKey.initialize());
100
101 return StatusCode::SUCCESS ;
102}
#define ATH_CHECK
Evaluate an expression and check for errors.
ServiceHandle< PileUpMergeSvc > m_mergeSvc
PileUp Merge service.

◆ mergeEvent()

StatusCode SCT_FastDigitizationTool::mergeEvent ( const EventContext & ctx)

Definition at line 205 of file SCT_FastDigitizationTool.cxx.

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}
AtlasHitsVector< SiHit > SiHitCollection
StatusCode digitize(const EventContext &ctx, TimedHitCollection< SiHit > &thpcsi)
TimedHitCollection< SiHit > * m_thpcsi
std::vector< SiHitCollection * > m_siHitCollList
name of the sub event hit collections.
StatusCode createAndStoreRIOs(const EventContext &ctx)
void * ptr(T *p)
Definition SGImplSvc.cxx:74

◆ NeighbouringClusters()

bool SCT_FastDigitizationTool::NeighbouringClusters ( const std::vector< Identifier > & potentialClusterRDOList,
const InDet::SCT_Cluster * existingCluster ) const
private

Definition at line 995 of file SCT_FastDigitizationTool.cxx.

996{
997 //---------------------------------------------------------------------------------
998 bool isNeighbour = false;
999 unsigned int countR(0);
1000 const std::vector<Identifier> &existingClusterRDOList = existingCluster->rdoList();
1001 std::vector<Identifier>::const_iterator potentialClusterRDOIter = potentialClusterRDOList.begin();
1002 for ( ; potentialClusterRDOIter != potentialClusterRDOList.end(); ++potentialClusterRDOIter)
1003 {
1004 ++countR;
1005 if (countR>100)
1006 {
1007 ATH_MSG_WARNING("Over 100 RDOs checked for the given cluster - bailing out!!");
1008 break;
1009 }
1010 std::vector<Identifier>::const_iterator existingClusterRDOIter = existingClusterRDOList.begin();
1011 for( ; existingClusterRDOIter != existingClusterRDOList.end(); ++existingClusterRDOIter)
1012 {
1013 if(std::abs(m_sct_ID->strip(*existingClusterRDOIter) - m_sct_ID->strip(*potentialClusterRDOIter)) < 2)
1014 {
1015 isNeighbour = true;
1016 break;
1017 }
1018 } // end of loop over RDOs in the current existing Cluster
1019 if (isNeighbour)
1020 {
1021 ATH_MSG_VERBOSE("The clusters are neighbours and can be merged.");
1022 break;
1023 }
1024 } // end of loop over RDOs in the potential cluster
1025 //---------------------------------------------------------------------------------
1026 return isNeighbour;
1027}

◆ prepareEvent()

StatusCode SCT_FastDigitizationTool::prepareEvent ( const EventContext & ctx,
unsigned int  )

Definition at line 104 of file SCT_FastDigitizationTool.cxx.

105{
106
107 m_siHitCollList.clear();
108 m_thpcsi = new TimedHitCollection<SiHit>();
110 return StatusCode::SUCCESS;
111
112}

◆ processAllSubEvents()

StatusCode SCT_FastDigitizationTool::processAllSubEvents ( const EventContext & ctx)
virtual

Reimplemented from PileUpToolBase.

Definition at line 155 of file SCT_FastDigitizationTool.cxx.

155 {
156
157 // get the container(s)
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}
IntegerProperty m_HardScatterSplittingMode
Process all SiHit or just those from signal or background events.
std::list< value_t > type
type of the collection of timed data object

◆ processBunchXing()

StatusCode SCT_FastDigitizationTool::processBunchXing ( int bunchXing,
SubEventIterator bSubEvents,
SubEventIterator eSubEvents )
virtual

Reimplemented from PileUpToolBase.

Definition at line 114 of file SCT_FastDigitizationTool.cxx.

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
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}
size_type size() const

◆ resetFilter()

virtual void PileUpToolBase::resetFilter ( )
inlineoverridevirtualinherited

dummy implementation of filter reset

Reimplemented in MergeTruthJetsTool.

Definition at line 51 of file PileUpToolBase.h.

51{ m_filterPassed=true; }

◆ stepToStripBorder()

Amg::Vector3D SCT_FastDigitizationTool::stepToStripBorder ( const InDetDD::SiDetectorElement & sidetel,
double localStartX,
double localStartY,
double localEndX,
double localEndY,
double slopeYX,
double slopeZX,
const Amg::Vector2D & stripCenter,
int direction )
staticprivate

Definition at line 950 of file SCT_FastDigitizationTool.cxx.

959{
960 double stepExitX = 0.;
961 double stepExitY = 0.;
962 double stepExitZ = 0.;
963 const double coef(1.);
964
965 // probably needs to be changed to rect/trapezoid
966 if (sidetel.isBarrel())
967 {
968 // the exit position of the new strip
969 double xExitPosition = stripCenter.x()+direction*0.5*sidetel.phiPitch(stripCenter);
970 stepExitX = xExitPosition-localStartX;
971 stepExitY = stepExitX*slopeYX;
972 stepExitZ = stepExitX*slopeZX;
973 }
974 else
975 {
976 // the end position of this particular strip
977 std::pair<Amg::Vector3D,Amg::Vector3D> stripEndGlobal = sidetel.endsOfStrip(stripCenter);
978 Amg::Vector3D oneStripEndLocal = coef*stripEndGlobal.first;
979 Amg::Vector3D twoStripEndLocal = coef*stripEndGlobal.second;
980
981 double oneStripPitch = sidetel.phiPitch(Amg::Vector2D(oneStripEndLocal.x(), oneStripEndLocal.y()));
982 double twoStripPitch = sidetel.phiPitch(Amg::Vector2D(twoStripEndLocal.x(), twoStripEndLocal.y()));
983 // now intersect track with border
984 Trk::LineIntersection2D intersectStripBorder(localStartX,localStartY,localEndX,localEndY,
985 oneStripEndLocal.x()+direction*0.5*oneStripPitch,oneStripEndLocal.y(),
986 twoStripEndLocal.x()+direction*0.5*twoStripPitch,twoStripEndLocal.y());
987 // the step in x
988 stepExitX = intersectStripBorder.interX - localStartX;
989 stepExitY = slopeYX*stepExitX;
990 stepExitZ = slopeZX*stepExitX;
991 }
992 return Amg::Vector3D(stepExitX,stepExitY,stepExitZ);
993}
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...
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.

◆ toProcess()

virtual bool PileUpToolBase::toProcess ( int bunchXing) const
inlineoverridevirtualinherited

the method this base class helps implementing

Reimplemented in MergeHijingParsTool, and MergeTrackRecordCollTool.

Definition at line 32 of file PileUpToolBase.h.

32 {
33 //closed interval [m_firstXing,m_lastXing]
34 return !((m_firstXing > bunchXing) || (bunchXing > m_lastXing));
35 }
Gaudi::Property< int > m_firstXing
Gaudi::Property< int > m_lastXing

Member Data Documentation

◆ m_clusterMaker

PublicToolHandle<InDet::ClusterMakerTool> SCT_FastDigitizationTool::m_clusterMaker {this, "ClusterMaker", "InDet::ClusterMakerTool"}
private

Definition at line 123 of file SCT_FastDigitizationTool.h.

123{this, "ClusterMaker", "InDet::ClusterMakerTool"};

◆ m_DiffusionShiftX_barrel

DoubleProperty SCT_FastDigitizationTool::m_DiffusionShiftX_barrel {this, "DiffusionShiftX_barrel",4 }
private

Definition at line 142 of file SCT_FastDigitizationTool.h.

142{this, "DiffusionShiftX_barrel",4 };

◆ m_DiffusionShiftX_endcap

DoubleProperty SCT_FastDigitizationTool::m_DiffusionShiftX_endcap {this, "DiffusionShiftX_endcap", 15}
private

Definition at line 144 of file SCT_FastDigitizationTool.h.

144{this, "DiffusionShiftX_endcap", 15};

◆ m_DiffusionShiftY_barrel

DoubleProperty SCT_FastDigitizationTool::m_DiffusionShiftY_barrel {this, "DiffusionShiftY_barrel", 4}
private

Definition at line 143 of file SCT_FastDigitizationTool.h.

143{this, "DiffusionShiftY_barrel", 4};

◆ m_DiffusionShiftY_endcap

DoubleProperty SCT_FastDigitizationTool::m_DiffusionShiftY_endcap {this, "DiffusionShiftY_endcap", 15}
private

Definition at line 145 of file SCT_FastDigitizationTool.h.

145{this, "DiffusionShiftY_endcap", 15};

◆ m_filterPassed

bool PileUpToolBase::m_filterPassed {true}
protectedinherited

Definition at line 60 of file PileUpToolBase.h.

60{true};

◆ m_firstXing

Gaudi::Property<int> PileUpToolBase::m_firstXing
protectedinherited
Initial value:
{this, "FirstXing", -999,
"First bunch-crossing in which det is live"}

Definition at line 54 of file PileUpToolBase.h.

54 {this, "FirstXing", -999,
55 "First bunch-crossing in which det is live"};

◆ m_HardScatterSplittingMode

IntegerProperty SCT_FastDigitizationTool::m_HardScatterSplittingMode {this, "HardScatterSplittingMode", 0, "Control pileup & signal splitting"}
private

Process all SiHit or just those from signal or background events.

Definition at line 115 of file SCT_FastDigitizationTool.h.

115{this, "HardScatterSplittingMode", 0, "Control pileup & signal splitting"};

◆ m_HardScatterSplittingSkipper

bool SCT_FastDigitizationTool::m_HardScatterSplittingSkipper {false}
private

Definition at line 116 of file SCT_FastDigitizationTool.h.

116{false};

◆ m_inputObjectName

StringProperty SCT_FastDigitizationTool::m_inputObjectName {this, "InputObjectName", "SCT_Hits", "Input Object name"}
private

Definition at line 109 of file SCT_FastDigitizationTool.h.

109{this, "InputObjectName", "SCT_Hits", "Input Object name"};

◆ m_lastXing

Gaudi::Property<int> PileUpToolBase::m_lastXing
protectedinherited
Initial value:
{this, "LastXing", 999,
"Last bunch-crossing in which det is live"}

Definition at line 56 of file PileUpToolBase.h.

56 {this, "LastXing", 999,
57 "Last bunch-crossing in which det is live"};

◆ m_lorentzAngleTool

ToolHandle<ISiLorentzAngleTool> SCT_FastDigitizationTool::m_lorentzAngleTool {this, "LorentzAngleTool", "SiLorentzAngleTool/SCTLorentzAngleTool", "Tool to retreive Lorentz angle"}
private

Definition at line 124 of file SCT_FastDigitizationTool.h.

124{this, "LorentzAngleTool", "SiLorentzAngleTool/SCTLorentzAngleTool", "Tool to retreive Lorentz angle"};

◆ m_mergeCluster

bool SCT_FastDigitizationTool::m_mergeCluster {true}
private

enable the merging of neighbour SCT clusters >

Definition at line 141 of file SCT_FastDigitizationTool.h.

141{true};

◆ m_mergeSvc

ServiceHandle<PileUpMergeSvc> SCT_FastDigitizationTool::m_mergeSvc {this, "MergeSvc", "PileUpMergeSvc", "Merge service"}
private

PileUp Merge service.

Definition at line 114 of file SCT_FastDigitizationTool.h.

114{this, "MergeSvc", "PileUpMergeSvc", "Merge service"};

◆ m_randomEngineName

StringProperty SCT_FastDigitizationTool::m_randomEngineName {this, "RndmEngine", "FastSCT_Digitization"}
private

Name of the random number stream.

Definition at line 119 of file SCT_FastDigitizationTool.h.

119{this, "RndmEngine", "FastSCT_Digitization"};

◆ m_rndmSvc

ServiceHandle<IAthRNGSvc> SCT_FastDigitizationTool::m_rndmSvc {this, "RndmSvc", "AthRNGSvc", ""}
private

Random number service.

Definition at line 118 of file SCT_FastDigitizationTool.h.

118{this, "RndmSvc", "AthRNGSvc", ""};

◆ m_sct_ID

const SCT_ID* SCT_FastDigitizationTool::m_sct_ID {}
private

Handle to the ID helper.

Definition at line 113 of file SCT_FastDigitizationTool.h.

113{};

◆ m_sctAnalogStripClustering

BooleanProperty SCT_FastDigitizationTool::m_sctAnalogStripClustering {this, "SCT_AnalogClustering", false}
private

not being done in ATLAS: analog strip clustering

Definition at line 137 of file SCT_FastDigitizationTool.h.

137{this, "SCT_AnalogClustering", false};

◆ m_sctClusterContainerKey

SG::WriteHandleKey<InDet::SCT_ClusterContainer> SCT_FastDigitizationTool::m_sctClusterContainerKey {this, "SCT_ClusterContainerName", "SCT_Clusters"}
private

the SCT_ClusterContainer

Definition at line 129 of file SCT_FastDigitizationTool.h.

129{this, "SCT_ClusterContainerName", "SCT_Clusters"};

◆ m_sctClusterMap

SCT_detElement_RIO_map* SCT_FastDigitizationTool::m_sctClusterMap {}
private

Definition at line 127 of file SCT_FastDigitizationTool.h.

127{};

◆ m_SCTDetEleCollKey

SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> SCT_FastDigitizationTool::m_SCTDetEleCollKey {this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"}
private

Definition at line 131 of file SCT_FastDigitizationTool.h.

131{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"};

◆ m_sctEmulateSurfaceCharge

BooleanProperty SCT_FastDigitizationTool::m_sctEmulateSurfaceCharge {this, "EmulateSurfaceCharge", true}
private

emulate the surface charge

Definition at line 135 of file SCT_FastDigitizationTool.h.

135{this, "EmulateSurfaceCharge", true};

◆ m_sctErrorStrategy

IntegerProperty SCT_FastDigitizationTool::m_sctErrorStrategy {this, "SCT_ErrorStrategy", 2}
private

error strategy for the ClusterMaker

Definition at line 138 of file SCT_FastDigitizationTool.h.

138{this, "SCT_ErrorStrategy", 2};

◆ m_sctMinimalPathCut

DoubleProperty SCT_FastDigitizationTool::m_sctMinimalPathCut {this, "SCT_MinimalPathLength", 90.}
private

the 1.

model parameter: minimal 3D path in strip

Definition at line 146 of file SCT_FastDigitizationTool.h.

146{this, "SCT_MinimalPathLength", 90.};

◆ m_sctPrdTruthKey

SG::WriteHandleKey<PRD_MultiTruthCollection> SCT_FastDigitizationTool::m_sctPrdTruthKey {this, "TruthNameSCT", "PRD_MultiTruthSCT"}
private

the PRD truth map for SCT measurements

Definition at line 130 of file SCT_FastDigitizationTool.h.

130{this, "TruthNameSCT", "PRD_MultiTruthSCT"};

◆ m_sctRotateEC

BooleanProperty SCT_FastDigitizationTool::m_sctRotateEC {this, "SCT_RotateEndcapClusters", true}
private

Definition at line 139 of file SCT_FastDigitizationTool.h.

139{this, "SCT_RotateEndcapClusters", true};

◆ m_sctSmearLandau

BooleanProperty SCT_FastDigitizationTool::m_sctSmearLandau {this, "SCT_SmearLandau", true}
private

if true : landau else: gauss

Definition at line 134 of file SCT_FastDigitizationTool.h.

134{this, "SCT_SmearLandau", true};

◆ m_sctSmearPathLength

DoubleProperty SCT_FastDigitizationTool::m_sctSmearPathLength {this, "SCT_SmearPathSigma", 0.01}
private

the 2.

model parameter: smear the path

Definition at line 133 of file SCT_FastDigitizationTool.h.

133{this, "SCT_SmearPathSigma", 0.01};

◆ m_sctTanLorentzAngleScalor

DoubleProperty SCT_FastDigitizationTool::m_sctTanLorentzAngleScalor {this, "SCT_ScaleTanLorentzAngle", 1.}
private

scale the lorentz angle effect

Definition at line 136 of file SCT_FastDigitizationTool.h.

136{this, "SCT_ScaleTanLorentzAngle", 1.};

◆ m_siHitCollList

std::vector<SiHitCollection*> SCT_FastDigitizationTool::m_siHitCollList
private

name of the sub event hit collections.

Definition at line 111 of file SCT_FastDigitizationTool.h.

◆ m_thpcsi

TimedHitCollection<SiHit>* SCT_FastDigitizationTool::m_thpcsi {}
private

Definition at line 121 of file SCT_FastDigitizationTool.h.

121{};

◆ m_vetoPileUpTruthLinks

Gaudi::Property<int> PileUpToolBase::m_vetoPileUpTruthLinks
protectedinherited
Initial value:
{this, "VetoPileUpTruthLinks", true,
"Ignore links to suppressed pile-up truth"}

Definition at line 58 of file PileUpToolBase.h.

58 {this, "VetoPileUpTruthLinks", true,
59 "Ignore links to suppressed pile-up truth"};

The documentation for this class was generated from the following files: