12#include "Identifier/Identifier.h"
28#include "CLHEP/Geometry/Point3D.h"
33#define AUXDATA(OBJ, TYP, NAME) \
34 static const SG::AuxElement::Accessor<TYP> acc_##NAME (#NAME); acc_##NAME(*(OBJ))
63 return StatusCode::SUCCESS;
74 std::map<Identifier, const SCT_RDORawData*> idToRAWDataMap;
79 for (
const auto collection: *rdoContainer) {
81 for (
const auto rdo : *collection) {
87 idToRAWDataMap.insert(std::pair<Identifier, const SCT_RDORawData*>{rdoId, rdo});
94 ATH_MSG_DEBUG(
"Size of RDO map is " << idToRAWDataMap.size());
100 if (prdmtCollHandle.
isValid()) {
101 prdmtColl = &*prdmtCollHandle;
105 if (truthParticleLinksHandle.
isValid()) {
106 truth_particle_links = truthParticleLinksHandle.
cptr();
114 if (sdoCollectionHandle.
isValid()) {
115 sdoCollection = &*sdoCollectionHandle;
119 std::vector<std::vector<const SiHit*>> siHits(
m_SCTHelper->wafer_hash_max());
129 sctDetEleHandle.
isValid() ? sctDetEleHandle.
cptr() :
nullptr;
130 if (sihitCollection.
isValid()) {
131 for (
const SiHit& siHit: *sihitCollection) {
133 if (not siHit.isSCT())
continue;
136 siHit.getLayerDisk(),
137 siHit.getPhiModule(),
138 siHit.getEtaModule(),
149 HepGeom::Point3D<double> avg{siHit.localStartPosition() + siHit.localEndPosition()};
156 const int rowOffset = mother->
getStripRow(mDiode).second;
157 if (rowOffset != 0) {
159 siHit.getLayerDisk(),
160 siHit.getPhiModule(),
161 siHit.getEtaModule() + rowOffset,
170 if (wafer_hash < siHits.size()) {
171 siHits[wafer_hash].push_back(&siHit);
174 << siHit.getEtaModule() <<
", hash " << wafer_hash <<
"), dropped");
182 if (not sctClusterContainer.
isValid()) {
184 return StatusCode::FAILURE;
189 ATH_CHECK(xaod.
record(std::make_unique<xAOD::TrackMeasurementValidationContainer>(),
190 std::make_unique<xAOD::TrackMeasurementValidationAuxContainer>()));
195 unsigned int have_truth_link=0u;
196 unsigned int missing_truth_particle=0u;
197 unsigned int missing_parent_particle=0u;
199 unsigned int counter{0};
200 for (
const auto clusterCollection: *sctClusterContainer) {
202 (*offsets)[clusterCollection->identifyHash()] = counter;
205 if (clusterCollection->empty())
continue;
207 xaod->resize(counter + clusterCollection->size());
217 xaod->at(counter) = xprd;
230 float locX{
static_cast<float>(locpos.x())};
231 if ((not std::isinf(locpos.y()) or std::isnan(locpos.y()))) {
232 if (locpos.y()>=1e-07) locY = locpos.y();
241 if (localCov.size() == 1) {
243 }
else if (localCov.size() == 4) {
250 std::vector<uint64_t> rdoIdentifierList;
251 rdoIdentifierList.reserve(prd->rdoList().size());
252 for (
const auto& hitIdentifier: prd->rdoList()) {
253 rdoIdentifierList.push_back(hitIdentifier.get_compact());
259 AUXDATA(xprd,
int, SiWidth) =
static_cast<int>(cw.
colRow()[0]);
260 AUXDATA(xprd,
int, hitsInThirdTimeBin) =
static_cast<int>(prd->hitsInThirdTimeBin());
271 uint64_t detElementId{0};
278 AUXDATA(xprd, uint64_t, detectorElementID) = detElementId;
288 auto range{prdmtColl->equal_range(clusterId)};
289 if (truth_particle_links) {
290 std::vector<unsigned int> tp_indices;
291 for (
auto i{range.first}; i!=range.second; ++i) {
293 if (a_truth_particle_link) {
295 if (truth_particle) {
297 tp_indices.push_back(
static_cast<int>(truth_particle->index()));
300 ++missing_parent_particle;
304 tp_indices.push_back(std::numeric_limits<unsigned int>::max());
305 ++missing_truth_particle;
308 AUXDATA(xprd, std::vector<unsigned int>, truth_index) = std::move(tp_indices);
310 std::vector<int> uniqueIDs;
311 for (
auto& i{range.first}; i!=range.second; ++i) {
314 AUXDATA(xprd, std::vector<int>, truth_barcode) = std::move(uniqueIDs);
320 std::vector<std::vector<int>> sdoTruthUIDs;
330 addSiHitInformation(xprd, prd, &siHits[prd->detectorElement()->identifyHash()], sdoTruthUIDs);
334 ATH_MSG_DEBUG(
" recorded SCT_PrepData objects: size " << xaod->size());
341 return StatusCode::SUCCESS;
348 std::vector<int> sdo_word;
349 std::vector<std::vector<int>> sdo_depositsUniqueID;
350 std::vector<std::vector<float>> sdo_depositsEnergy;
352 for (
const auto& hitIdentifier: prd->
rdoList()) {
353 auto pos{sdoCollection->find(hitIdentifier)};
354 if (pos == sdoCollection->end())
continue;
355 sdo_word.push_back(pos->second.word());
357 std::vector<float> sdoDepEnergy(pos->second.getdeposits().size());
358 unsigned int nDepos{0};
359 for (
auto& deposit: pos->second.getdeposits()) {
360 if (deposit.first) sdoDepUniqueID[nDepos] =
HepMC::uniqueID(deposit.first);
362 sdoDepEnergy[nDepos] = deposit.second;
365 sdo_depositsUniqueID.push_back(std::move(sdoDepUniqueID));
366 sdo_depositsEnergy.push_back(std::move(sdoDepEnergy));
368 AUXDATA(xprd, std::vector<int>, sdo_words) = std::move(sdo_word);
369 AUXDATA(xprd, std::vector<std::vector<int>>, sdo_depositsBarcode) = sdo_depositsUniqueID;
370 AUXDATA(xprd, std::vector<std::vector<float>>, sdo_depositsEnergy) = std::move(sdo_depositsEnergy);
371 return sdo_depositsUniqueID;
377 const std::vector<const SiHit*>* siHits,
378 const std::vector<std::vector<int>>& sdoTruthUIDs)
const
380 std::vector<SiHit> matchingHits;
383 long unsigned int numHits{matchingHits.size()};
385 std::vector<float> sihit_energyDeposit(numHits, 0.);
386 std::vector<float> sihit_meanTime(numHits, 0.);
389 std::vector<float> sihit_startPosX(numHits, 0.);
390 std::vector<float> sihit_startPosY(numHits, 0.);
391 std::vector<float> sihit_startPosZ(numHits, 0.);
393 std::vector<float> sihit_endPosX(numHits, 0);
394 std::vector<float> sihit_endPosY(numHits, 0);
395 std::vector<float> sihit_endPosZ(numHits, 0);
409 double alongStripShift = 0.;
411 if (d->getMother()) {
412 alongStripShift = d->moduleShift().translation().x();
416 for (
const SiHit& sihit : matchingHits) {
417 sihit_energyDeposit[hitNumber] = sihit.energyLoss();
418 sihit_meanTime[hitNumber] = sihit.meanTime();
423 const HepGeom::Point3D<double> s{de->
hitLocalToLocal3D(sihit.localStartPosition())};
424 sihit_startPosX[hitNumber] = s.x();
425 sihit_startPosY[hitNumber] = s.y() - alongStripShift;
426 sihit_startPosZ[hitNumber] = s.z();
428 const HepGeom::Point3D<double> e{de->
hitLocalToLocal3D(sihit.localEndPosition())};
429 sihit_endPosX[hitNumber] = e.x();
430 sihit_endPosY[hitNumber] = e.y() - alongStripShift;
431 sihit_endPosZ[hitNumber] = e.z();
436 AUXDATA(xprd, std::vector<float>, sihit_energyDeposit) = std::move(sihit_energyDeposit);
437 AUXDATA(xprd, std::vector<float>, sihit_meanTime) = std::move(sihit_meanTime);
438 AUXDATA(xprd, std::vector<int>, sihit_barcode) = std::move(sihit_uniqueID);
440 AUXDATA(xprd, std::vector<float>, sihit_startPosX) = std::move(sihit_startPosX);
441 AUXDATA(xprd, std::vector<float>, sihit_startPosY) = std::move(sihit_startPosY);
442 AUXDATA(xprd, std::vector<float>, sihit_startPosZ) = std::move(sihit_startPosZ);
444 AUXDATA(xprd, std::vector<float>, sihit_endPosX) = std::move(sihit_endPosX);
445 AUXDATA(xprd, std::vector<float>, sihit_endPosY) = std::move(sihit_endPosY);
446 AUXDATA(xprd, std::vector<float>, sihit_endPosZ) = std::move(sihit_endPosZ);
450 const std::vector<const SiHit*>* siHits,
451 const std::vector<std::vector<int>>& sdoTruthUIDs,
452 std::vector<SiHit>& matchingHits)
const
454 ATH_MSG_VERBOSE(
"Got " << siHits->size() <<
" SiHits to look through");
458 if (de==
nullptr)
return;
460 std::vector<const SiHit*> multiMatchingHits;
462 for (
const SiHit* siHit: *siHits) {
467 bool matched =
false;
469 HepGeom::Point3D<double> averagePosition{siHit->localStartPosition() + siHit->localEndPosition()};
470 averagePosition *= 0.5;
475 for (
const auto& hitIdentifier: prd->
rdoList()) {
479 multiMatchingHits.push_back(siHit);
487 for (
const auto& uniqueIDSDOColl: sdoTruthUIDs) {
488 if (std::find(uniqueIDSDOColl.begin(), uniqueIDSDOColl.end(), uid) == uniqueIDSDOColl.end())
continue;
489 multiMatchingHits.push_back(siHit);
495 matchingHits.reserve(multiMatchingHits.size());
497 std::vector<const SiHit*>::iterator siHitIter{multiMatchingHits.begin()};
498 std::vector<const SiHit*>::iterator siHitIter2{multiMatchingHits.begin()};
499 ATH_MSG_DEBUG(
"Found " << multiMatchingHits.size() <<
" SiHit ");
500 for (; siHitIter != multiMatchingHits.end(); ++siHitIter) {
501 const SiHit* lowestXPos{*siHitIter};
502 const SiHit* highestXPos{*siHitIter};
505 std::vector<const SiHit*> ajoiningHits;
506 ajoiningHits.push_back(*siHitIter);
508 siHitIter2 = siHitIter+1;
510 while (siHitIter2 != multiMatchingHits.end()) {
517 constexpr double maxDiff = 0.00005;
519 if (std::abs((highestXPos->
localEndPosition().x()-(*siHitIter2)->localStartPosition().x()))<maxDiff and
520 std::abs((highestXPos->
localEndPosition().y()-(*siHitIter2)->localStartPosition().y()))<maxDiff and
521 std::abs((highestXPos->
localEndPosition().z()-(*siHitIter2)->localStartPosition().z()))<maxDiff) {
522 highestXPos = *siHitIter2;
523 ajoiningHits.push_back(*siHitIter2);
525 siHitIter2 = multiMatchingHits.erase(siHitIter2);
526 }
else if (std::abs((lowestXPos->
localStartPosition().x()-(*siHitIter2)->localEndPosition().x()))<maxDiff and
527 std::abs((lowestXPos->
localStartPosition().y()-(*siHitIter2)->localEndPosition().y()))<maxDiff and
528 std::abs((lowestXPos->
localStartPosition().z()-(*siHitIter2)->localEndPosition().z()))<maxDiff) {
529 lowestXPos = *siHitIter2;
530 ajoiningHits.push_back(*siHitIter2);
532 siHitIter2 = multiMatchingHits.erase(siHitIter2);
538 if (ajoiningHits.size()==0) {
541 }
else if (ajoiningHits.size()==1) {
543 matchingHits.emplace_back(*ajoiningHits[0]);
547 ATH_MSG_DEBUG(
"Merging " << ajoiningHits.size() <<
" SiHits together.");
550 for (
auto& siHit: ajoiningHits) {
551 energyDep += siHit->energyLoss();
552 time += siHit->meanTime();
554 time /=
static_cast<float>(ajoiningHits.size());
559 (*siHitIter)->particleLink(),
561 (*siHitIter)->getBarrelEndcap(),
562 (*siHitIter)->getLayerDisk(),
563 (*siHitIter)->getEtaModule(),
564 (*siHitIter)->getPhiModule(),
565 (*siHitIter)->getSide());
572 const std::map<Identifier, const SCT_RDORawData*>& idToRAWDataMap)
const {
574 std::vector<int> timebin(prd->
rdoList().size(), -1);
575 std::vector<int> groupsize(prd->
rdoList().size(), -1);
577 unsigned int nRDOs{0};
578 for (
const auto& hitIdentifier: prd->
rdoList()) {
579 auto result{idToRAWDataMap.find(hitIdentifier)};
580 if (result != idToRAWDataMap.end()) {
594 AUXDATA(xprd, std::vector<int>, rdo_strip) = std::move(
strip);
595 AUXDATA(xprd, std::vector<int>, rdo_timebin) = std::move(timebin);
596 AUXDATA(xprd, std::vector<int>, rdo_groupsize) = std::move(groupsize);
610 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
#define AUXDATA(OBJ, TYP, NAME)
This is an Identifier helper class for the SCT subdetector.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
const ServiceHandle< StoreGateSvc > & detStore() const
ElementLink implementation for ROOT usage.
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
value_type get_compact() const
Get the compact id.
virtual SiCellId cellIdOfPosition(const SiLocalPosition &localPos) const =0
position -> id
Base class for the SCT module side design, extended by the Forward and Barrel module design.
virtual std::pair< int, int > getStripRow(SiCellId id) const
Get the strip and row number of the cell.
const SCT_ModuleSideDesign * getMother() const
Identifier for the strip or pixel cell.
int phiIndex() const
Get phi index. Equivalent to strip().
bool isValid() const
Test if its in a valid state.
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
virtual Identifier identify() const override final
identifier of this detector element (inline)
virtual Identifier identify() const override final
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
const Amg::Vector2D & colRow() const
A PRD is mapped onto all contributing particles.
virtual int getGroupSize() const override final
std::atomic< unsigned int > m_missingParentParticle
void findAllHitsCompatibleWithCluster(const InDet::SCT_Cluster *prd, const std::vector< const SiHit * > *siHits, const std::vector< std::vector< int > > &sdoTruthUIDs, std::vector< SiHit > &matchingHits) const
BooleanProperty m_useSiHitsGeometryMatching
SG::ReadHandleKey< SiHitCollection > m_sihitContainer
SG::ReadHandleKey< PRD_MultiTruthCollection > m_multiTruth
SG::ReadHandleKey< SCT_RDO_Container > m_rdoContainer
BooleanProperty m_writeSDOs
SG::ReadHandleKey< InDetSimDataCollection > m_SDOcontainer
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
virtual StatusCode execute(const EventContext &ctx) const override
std::atomic_bool m_firstEventWarnings
BooleanProperty m_writeSiHits
SG::WriteHandleKey< xAOD::TrackMeasurementValidationContainer > m_xAodContainer
std::vector< std::vector< int > > addSDOInformation(xAOD::TrackMeasurementValidation *xprd, const InDet::SCT_Cluster *prd, const InDetSimDataCollection *sdoCollection) const
Decorate the cluster with SDO truth information and return, per RDO, the uniqueIDs of the truth parti...
virtual StatusCode finalize() override
SG::WriteHandleKey< std::vector< unsigned int > > m_xAodOffset
void addSiHitInformation(xAOD::TrackMeasurementValidation *xprd, const InDet::SCT_Cluster *prd, const std::vector< const SiHit * > *siHits, const std::vector< std::vector< int > > &sdoTruthUIDs) const
BooleanProperty m_writeRDOinformation
const SCT_ID * m_SCTHelper
SG::ReadHandleKey< xAODTruthParticleLinkVector > m_truthParticleLinks
std::atomic< unsigned int > m_missingTruthParticle
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_clustercontainer
void addRDOInformation(xAOD::TrackMeasurementValidation *, const InDet::SCT_Cluster *, const std::map< Identifier, const SCT_RDORawData * > &idToRAWDataMap) const
std::atomic< unsigned int > m_haveTruthLink
BooleanProperty m_useTruthInfo
virtual StatusCode initialize() override
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
HepGeom::Point3D< double > localStartPosition() const
HepGeom::Point3D< double > localEndPosition() const
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
ElementLink< xAOD::TruthParticleContainer > find(const HepMcParticleLink &hepMCLink) const
void setRdoIdentifierList(const std::vector< uint64_t > &rdoIdentifierList)
Sets the list of RDO identifiers.
void setLocalPositionError(float localXError, float localYError, float localXYCorrelation)
Sets the local position error.
void setLocalPosition(float localX, float localY)
Sets the local position.
void setIdentifier(uint64_t identifier)
Sets the identifier.
void setGlobalPosition(float globalX, float globalY, float globalZ)
Sets the global position.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr int INVALID_PARTICLE_ID
constexpr int UNDEFINED_ID
TrackMeasurementValidation_v1 TrackMeasurementValidation
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.