ATLAS Offline Software
Loading...
Searching...
No Matches
SiSmearedDigitizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// SiSmearedDigitizationTool.cxx
7// Implementation file for class SiSmearedDigitizationTool
9
10// Pixel digitization includes
12
13// Det Descr
14#include "Identifier/Identifier.h"
17
23
24// Random numbers
26#include "CLHEP/Random/RandGaussZiggurat.h"
27#include "CLHEP/Random/RandFlat.h"
28#include "CLHEP/Random/RandGauss.h"
29#include "CLHEP/Random/RandLandau.h"
30#include "CLHEP/Vector/ThreeVector.h"
31
32// Pile-up
34
39
40// Fatras
51
53
54// Root
55#include "TTree.h"
56#include "TFile.h"
57
58#include <cmath>
59#include <memory>
60
61using namespace InDetDD;
62
63// Constructor with parameters:
64SiSmearedDigitizationTool::SiSmearedDigitizationTool(const std::string &type, const std::string &name,
65 const IInterface* parent):
66 PileUpToolBase(type, name, parent),
67 m_pixel_ID(nullptr),
68 m_sct_ID(nullptr),
69 m_randomEngineName("SiSmearedDigitization"),
70 m_pitch_X(0),
71 m_pitch_Y(0),
72 m_merge(false),
73 m_nSigma(0.),
74 m_useDiscSurface(false),
76 m_sctClusterContainer(nullptr),
77 m_mergeSvc("PileUpMergeSvc",name),
80 m_prdTruthNamePixel("PRD_MultiTruthPixel"),
81 m_prdTruthNameSCT("PRD_MultiTruthSCT"),
82 m_SmearPixel(true), //true: smear pixel --- false: smear SCT
83 m_emulateAtlas(true), // error rotation for endcap SCT
84 m_checkSmear(false),
85 m_outputFile(nullptr),
86 m_currentTree(nullptr),
87 m_x_pixel(0),
88 m_y_pixel(0),
98 m_x_SCT(0),
99 m_x_exit_SCT(0),
100 m_y_exit_SCT(0),
101 m_z_exit_SCT(0),
102 m_x_entry_SCT(0),
103 m_y_entry_SCT(0),
104 m_z_entry_SCT(0),
111 m_Err_x_pixel(0),
112 m_Err_y_pixel(0),
113 m_Err_x_SCT(0),
114 m_Err_y_SCT(0)
115{
116 declareProperty("RndmEngine", m_randomEngineName, "Random engine name");
117 declareProperty("InputObjectName", m_inputObjectName="PixelHits", "Input Object name" );
118 declareProperty("pitch_X", m_pitch_X);
119 declareProperty("pitch_Y", m_pitch_Y);
120 declareProperty("MergeClusters", m_merge);
121 declareProperty("Nsigma", m_nSigma);
122 declareProperty("SmearPixel", m_SmearPixel, "Enable Pixel or SCT Smearing");
123 declareProperty("PixelClusterContainerName", m_pixel_SiClustersName="PixelClusters");
124 declareProperty("SCT_ClusterContainerName", m_Sct_SiClustersName="SCT_Clusters");
125 declareProperty("CheckSmear", m_checkSmear);
126
127 declareProperty("HardScatterSplittingMode" , m_HardScatterSplittingMode, "Control pileup & signal splitting" );
128
129}
130
131
132// Initialize method:
134{
135
136 ATH_MSG_DEBUG ( "SiSmearedDigitizationTool::initialize()" );
137
138 //locate the AtRndmGenSvc and initialize our local ptr
139 if (!m_rndmSvc.retrieve().isSuccess())
140 {
141 ATH_MSG_ERROR ( "Could not find given RndmSvc" );
142 return StatusCode::FAILURE;
143 }
144
145 if (detStore()->retrieve(m_pixel_ID, "PixelID").isFailure()) {
146 ATH_MSG_ERROR ( "Could not get Pixel ID helper" );
147 return StatusCode::FAILURE;
148 }
149
150 if (not m_SmearPixel){ // Smear SCT
151 if (detStore()->retrieve(m_sct_ID, "SCT_ID").isFailure()) {
152 ATH_MSG_ERROR ( "Could not get SCT ID helper" );
153 return StatusCode::FAILURE;
154 }
155
156 m_inputObjectName="SCT_Hits"; // Set the input object name
157 }
158
159 // Initialize ReadCondHandleKeys
162
163 if (m_inputObjectName.empty())
164 {
165 ATH_MSG_FATAL ( "Property InputObjectName not set !" );
166 return StatusCode::FAILURE;
167 }
168 else
169 {
170 ATH_MSG_DEBUG ( "Input objects: '" << m_inputObjectName << "'" );
171 }
172
173 //locate the PileUpMergeSvc and initialize our local ptr
174 if (!m_mergeSvc.retrieve().isSuccess()) {
175 ATH_MSG_ERROR ( "Could not find PileUpMergeSvc" );
176 return StatusCode::FAILURE;
177 }
178
179 if (m_checkSmear){
180
181 // get THistSvc
182 ATH_CHECK(m_thistSvc.retrieve());
183
184 if (m_SmearPixel){
185 m_outputFile = new TFile("CheckSmearing_Pixel.root","RECREATE");
186 m_currentTree = new TTree("PixelTree","Check smearing Pixel");
187 m_currentTree->Branch("pixel_X" , &m_x_pixel , "m_x_pixel/D");
188 m_currentTree->Branch("pixel_Y" , &m_y_pixel , "m_y_pixel/D");
189 m_currentTree->Branch("pixel_X_exit" , &m_x_exit_pixel , "m_x_exit_pixel/D");
190 m_currentTree->Branch("pixel_Y_exit" , &m_y_exit_pixel , "m_y_exit_pixel/D");
191 m_currentTree->Branch("pixel_Z_exit" , &m_z_exit_pixel , "m_z_exit_pixel/D");
192 m_currentTree->Branch("pixel_X_entry" , &m_x_entry_pixel , "m_x_entry_pixel/D");
193 m_currentTree->Branch("pixel_Y_entry" , &m_y_entry_pixel , "m_y_entry_pixel/D");
194 m_currentTree->Branch("pixel_Z_entry" , &m_z_entry_pixel , "m_z_entry_pixel/D");
195 m_currentTree->Branch("pixel_X_global" , &m_x_pixel_global , "m_x_pixel_global/D");
196 m_currentTree->Branch("pixel_Y_global" , &m_y_pixel_global , "m_y_pixel_global/D");
197 m_currentTree->Branch("pixel_Z_global" , &m_z_pixel_global , "m_z_pixel_global/D");
198 m_currentTree->Branch("pixel_X_smear" , &m_x_pixel_smeared , "m_x_pixel_smeared/D");
199 m_currentTree->Branch("pixel_Y_smear" , &m_y_pixel_smeared , "m_y_pixel_smeared/D");
200 m_currentTree->Branch("pixel_Err_X" , &m_Err_x_pixel , "m_Err_x_pixel/D");
201 m_currentTree->Branch("pixel_Err_Y" , &m_Err_y_pixel , "m_Err_y_pixel/D");
202
203 if( m_thistSvc->regTree("PixelTree",m_currentTree).isFailure()) {
204 ATH_MSG_ERROR("Cannot register Ttree");
205 return StatusCode::FAILURE;
206 }else{
207 ATH_MSG_DEBUG ( "Ttree registered" );
208 }
209 }
210 else{
211 m_outputFile = new TFile("CheckSmearing_SCT.root","RECREATE");
212 m_currentTree = new TTree("SCT_Tree","Check smearing SCT");
213 m_currentTree->Branch("SCT_X" , &m_x_SCT , "m_x_SCT/D");
214 m_currentTree->Branch("SCT_exit_X" , &m_x_exit_SCT , "m_x_exit_SCT/D");
215 m_currentTree->Branch("SCT_exit_Y" , &m_y_exit_SCT , "m_y_exit_SCT/D");
216 m_currentTree->Branch("SCT_exit_Z" , &m_z_exit_SCT , "m_z_exit_SCT/D");
217 m_currentTree->Branch("SCT_entry_X" , &m_x_entry_SCT , "m_x_entry_SCT/D");
218 m_currentTree->Branch("SCT_entry_Y" , &m_y_entry_SCT , "m_y_entry_SCT/D");
219 m_currentTree->Branch("SCT_entry_Z" , &m_z_entry_SCT , "m_z_entry_SCT/D");
220 m_currentTree->Branch("SCT_X_global" , &m_x_SCT_global , "m_x_SCT_global/D");
221 m_currentTree->Branch("SCT_Y_global" , &m_y_SCT_global , "m_y_SCT_global/D");
222 m_currentTree->Branch("SCT_Z_global" , &m_z_SCT_global , "m_z_SCT_global/D");
223 m_currentTree->Branch("SCT_X_smear" , &m_x_SCT_smeared , "m_x_SCT_smeared/D");
224 m_currentTree->Branch("SCT_Err_X" , &m_Err_x_SCT , "m_Err_x_SCT/D");
225
226 if( m_thistSvc->regTree("SCT_Tree",m_currentTree).isFailure()) {
227 ATH_MSG_ERROR("Cannot register Ttree");
228 return StatusCode::FAILURE;
229 }else{
230 ATH_MSG_DEBUG ( "Ttree registered" );
231 }
232 }
233
234
235 }
236
237 return StatusCode::SUCCESS;
238}
239
240// Finalize method:
242{
243
244 if (m_checkSmear){
245 m_outputFile->cd();
246 m_currentTree->Write();
247 m_outputFile->Close();
248 ATH_MSG_DEBUG ( "SiSmearedDigitizationTool : Writing Tree" );
249
250 }
251
252 ATH_MSG_DEBUG ( "SiSmearedDigitizationTool : finalize()" );
253
254
255 return StatusCode::SUCCESS;
256
257}
258
259StatusCode SiSmearedDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
260{
261
262 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel prepareEvent() ---" );
263
264 m_siHitCollList.clear();
266
267 return StatusCode::SUCCESS;
268}
269
270
272 SubEventIterator bSubEvents,
273 SubEventIterator eSubEvents)
274{
275 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel processBunchXing() ---" );
276 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
277 if (m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
278 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
280
282 TimedHitCollList hitCollList;
283
284 if (!(m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName, hitCollList, bunchXing,
285 bSubEvents, eSubEvents).isSuccess()) &&
286 hitCollList.empty()) {
287 ATH_MSG_ERROR("Could not fill TimedHitCollList");
288 return StatusCode::FAILURE;
289 } else {
290 ATH_MSG_VERBOSE(hitCollList.size() << " SiHitCollections with key " <<
291 m_inputObjectName << " found");
292 }
293
294 TimedHitCollList::iterator iColl(hitCollList.begin());
295 TimedHitCollList::iterator endColl(hitCollList.end());
296
297 for( ; iColl != endColl; ++iColl) {
298 SiHitCollection *siHitColl = new SiHitCollection(*iColl->second);
299 PileUpTimeEventIndex timeIndex(iColl->first);
300 ATH_MSG_DEBUG("SiHitCollection found with " << siHitColl->size() <<
301 " hits");
302 ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
303 << " index: " << timeIndex.index()
304 << " type: " << timeIndex.type());
305 m_siHitCollList.push_back(siHitColl);
306 }
307
308 return StatusCode::SUCCESS;
309}
310
311
312StatusCode SiSmearedDigitizationTool::processAllSubEvents(const EventContext& ctx) {
313
314 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel processAllSubEvents() ---" );
315
316 if(m_SmearPixel){ // Smear Pixel
317 // --------------------------------------
318 // PixelCluster container registration
319 unsigned int nwafer = m_pixel_ID->wafer_hash_max();
321 ATH_CHECK( wh.record (std::make_unique<InDet::PixelClusterContainer>(nwafer)) );
322 m_pixelClusterContainer = wh.ptr();
323 m_pixelClusterContainer->cleanup();
324
325 // symlink the Pixel Container
326 // FIXME: This results in a hard cast, which is undefined behavior as per C++.
328
329 }else{ // Smear SCT
330 // --------------------------------------
331 // SCT_Cluster container registration
332 unsigned int nwafer = m_sct_ID->wafer_hash_max();
334 ATH_CHECK( wh.record (std::make_unique<InDet::SCT_ClusterContainer>(nwafer)) );
335 m_sctClusterContainer = wh.ptr();
336 m_sctClusterContainer->cleanup();
337
338 // symlink the SCT Container
339 // FIXME: This results in a hard cast, which is undefined behavior as per C++.
341 }
342
343 if (retrieveTruth().isFailure()) {
344 ATH_MSG_FATAL ( "retrieveTruth() failed!" );
345 return StatusCode::FAILURE;
346 }
347
348 // get the container(s)
350
352
353 //this is a list<pair<time_t, DataLink<SCTUncompressedHitCollection> > >
354 TimedHitCollList hitCollList;
355 unsigned int numberOfSimHits(0);
356 if ( !(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
357 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
358 return StatusCode::FAILURE;
359 } else {
360 ATH_MSG_DEBUG ( hitCollList.size() << " SiHitCollections with key " << m_inputObjectName << " found" );
361 }
362
363 // Define Hit Collection
364 TimedHitCollection<SiHit> thpcsi(numberOfSimHits);
365
366 //now merge all collections into one
367 TimedHitCollList::iterator iColl(hitCollList.begin());
368 TimedHitCollList::iterator endColl(hitCollList.end() );
369
371 // loop on the hit collections
372 while ( iColl != endColl ) {
374 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
376 const SiHitCollection* p_collection(iColl->second);
377 thpcsi.insert(iColl->first, p_collection);
378 ATH_MSG_DEBUG ( "SiHitCollection found with " << p_collection->size() << " hits" );
379 ++iColl;
380 }
381
382 // Process the Hits straw by straw: get the iterator pairs for given straw
383 if(this->digitize(ctx, thpcsi).isFailure()) {
384 ATH_MSG_FATAL ( "digitize method failed!" );
385 return StatusCode::FAILURE;
386 }
387
388 if (m_merge)
389 if(this->mergeEvent(ctx).isFailure()) {
390 ATH_MSG_FATAL ( "merge method failed!" );
391 return StatusCode::FAILURE;
392 }
393
394 if (createAndStoreRIOs(ctx).isFailure()) {
395 ATH_MSG_FATAL ( "createAndStoreRIOs() failed!" );
396 return StatusCode::FAILURE;
397 }
398 else {
399 ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
400 }
401
402 return StatusCode::SUCCESS;
403
404}
405
407
408
409 if(m_SmearPixel){ // Smear Pixel
410
412
414 if((evtStore()->retrieve(m_pixelPrdTruth, m_prdTruthNamePixel)).isFailure()){
415 ATH_MSG_FATAL("Could not retrieve collection " << m_prdTruthNamePixel);
416 return StatusCode::FAILURE;
417 }
418 }else{
419 if((evtStore()->record(m_pixelPrdTruth, m_prdTruthNamePixel)).isFailure()){
420 ATH_MSG_FATAL("Could not record collection " << m_prdTruthNamePixel);
421 return StatusCode::FAILURE;
422 }
423 }
424 }else{ // Smear SCT
426
428 if((evtStore()->retrieve(m_SCTPrdTruth, m_prdTruthNameSCT)).isFailure()){
429 ATH_MSG_FATAL("Could not retrieve collection " << m_prdTruthNameSCT);
430 return StatusCode::FAILURE;
431 }
432 }else{
433 if((evtStore()->record(m_SCTPrdTruth, m_prdTruthNameSCT)).isFailure()){
434 ATH_MSG_FATAL("Could not record collection " << m_prdTruthNameSCT);
435 return StatusCode::FAILURE;
436 }
437 }
438 }
439
440
441 return StatusCode::SUCCESS;
442
443}
444
445template<typename CLUSTER>
447
448 ATH_MSG_DEBUG("Truth map filling with cluster " << *cluster << " and link = " << hit->particleLink());
449 if (hit->particleLink().isValid()){
450 if (!HepMC::ignoreTruthLink(hit->particleLink(), m_vetoPileUpTruthLinks)) {
451 map->insert(std::make_pair(cluster->identify(), hit->particleLink()));
452 ATH_MSG_DEBUG("Truth map filled with cluster " << *cluster << " and link = " << hit->particleLink());
453 }
454 }else{
455 ATH_MSG_DEBUG("Particle link NOT valid!! Truth map NOT filled with cluster" << cluster << " and link = " << hit->particleLink());
456 }
457
458 return StatusCode::SUCCESS;
459}
460
461StatusCode SiSmearedDigitizationTool::mergeEvent(const EventContext& /*ctx*/){
462
463 if (m_SmearPixel)
465 else
467}
468
469template<typename CLUSTER>
471
472 // take needed information on the first clusters
473 Amg::Vector2D intersection_a = clusterA->localPosition();
474
475 // take needed information on the second clusters
476 Amg::Vector2D intersection_b = clusterB->localPosition();
477
478 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection_a = " << intersection_a);
479 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection_b = " << intersection_b);
480
481 double distX = intersection_a.x() - intersection_b.x();
482 double distY = intersection_a.y() - intersection_b.y();
483
484 return sqrt(distX*distX + distY*distY);
485}
486
487template<typename CLUSTER>
489 // take needed information on the first cluster
490 const Amg::MatrixX& clusterErr_a = clusterA->localCovariance();
491
492 // take needed information on the second clusters
493 const Amg::MatrixX& clusterErr_b = clusterB->localCovariance();
494
495 double sigmaX = sqrt(Amg::error(clusterErr_a,Trk::locX) * Amg::error(clusterErr_a,Trk::locX) +
496 Amg::error(clusterErr_b,Trk::locX) * Amg::error(clusterErr_b,Trk::locX));
497
498 double sigmaY = sqrt(Amg::error(clusterErr_a,Trk::locY) * Amg::error(clusterErr_a,Trk::locY) +
499 Amg::error(clusterErr_b,Trk::locY) * Amg::error(clusterErr_b,Trk::locY));
500
501 return sqrt(sigmaX*sigmaX + sigmaY*sigmaY);
502}
503
504template<typename CLUSTER>
506 // take needed information on the first clusters
507 Amg::Vector2D intersection_a = clusterA->localPosition();
508 const Amg::MatrixX& clusterErr_a = clusterA->localCovariance();
509
510 // take needed information on the second clusters
511 Amg::Vector2D intersection_b = clusterB->localPosition();
512 const Amg::MatrixX& clusterErr_b = clusterB->localCovariance();
513
514 double sigmaX = sqrt(Amg::error(clusterErr_a,Trk::locX) * Amg::error(clusterErr_a,Trk::locX) +
515 Amg::error(clusterErr_b,Trk::locX) * Amg::error(clusterErr_b,Trk::locX));
516
517 double sigmaY = sqrt(Amg::error(clusterErr_a,Trk::locY) * Amg::error(clusterErr_a,Trk::locY) +
518 Amg::error(clusterErr_b,Trk::locY) * Amg::error(clusterErr_b,Trk::locY));
519
520 double interX = 0.5*(intersection_a.x()+intersection_b.x());
521 double interY = 0.5*(intersection_a.y()+intersection_b.y());
522
523 Amg::Vector2D intersection(interX, interY);
524
525 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection = " << intersection);
526
527 const InDet::SiWidth& siWidth_a = clusterA->width();
528 const InDet::SiWidth& siWidth_b = clusterB->width();
529
530 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth_a = " << siWidth_a);
531 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth_b = " << siWidth_b);
532
533 Amg::Vector2D colRow = siWidth_a.colRow() + siWidth_b.colRow();
534 Amg::Vector2D phiRz = siWidth_a.widthPhiRZ() + siWidth_b.widthPhiRZ();
535
536 InDet::SiWidth siWidth(colRow, phiRz);
537
538 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth = " << siWidth);
539
540 AmgSymMatrix(2) covariance;
541 covariance.setIdentity();
542 covariance(Trk::locX,Trk::locX) = sigmaX*sigmaX;
543 covariance(Trk::locY,Trk::locY) = sigmaY*sigmaY;
544 Amg::MatrixX clusterErr = covariance;
545
546 return ClusterInfo( intersection, siWidth, clusterErr );
547
548}
549
551{
552 // The idea is first to check how many cluster we have to merge and then merge them.
553 // The loop is done until there aren't any clusters to merge
554
555 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in mergeClusters() using PixelClusters --- ");
556
557 Pixel_detElement_RIO_map::iterator i = cluster_map->begin();
558 Pixel_detElement_RIO_map::iterator e = cluster_map->end();
559
560 for (; i != e; i = cluster_map->upper_bound(i->first)){
561 IdentifierHash current_id = i->first;
562 // Check if clusters with current_id have been already considered
563
564 bool NewMerge = true;
565
566 while (NewMerge) {
567 NewMerge = false;
568 std::pair <Pixel_detElement_RIO_map::iterator, Pixel_detElement_RIO_map::iterator> range = cluster_map->equal_range(current_id);
569
570 for ( Pixel_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter){
571 for (Pixel_detElement_RIO_map::iterator inner_iter = std::next(iter); inner_iter != range.second; ++inner_iter){
572
573 double dist = calculateDistance((*iter).second,(*inner_iter).second);
574 double sigma = calculateSigma((*iter).second,(*inner_iter).second);
575
576 if( dist <= m_nSigma * sigma) {
577
578 std::vector<Identifier> rdoList;
579
581 InDet::SiWidth siWidth;
582 Amg::MatrixX clusterErr;
583 std::tie( intersection, siWidth, clusterErr ) = calculateNewCluster( iter->second, inner_iter->second );
584
585 const InDetDD::SiDetectorElement* hitSiDetElement = (((*inner_iter).second)->detectorElement());
586 Identifier intersectionId = hitSiDetElement->identifierOfPosition(intersection);
587
588 rdoList.push_back(intersectionId);
589
590 InDetDD::SiCellId currentCellId = hitSiDetElement->cellIdFromIdentifier(intersectionId);
591
592 if ( !currentCellId.isValid() ) {
593 continue;
594 }
595
596 InDet::PixelCluster* pixelCluster = new InDet::PixelCluster(intersectionId,
598 std::move(rdoList),
599 siWidth,
600 hitSiDetElement,
601 std::move(clusterErr));
602 ((*inner_iter).second) = pixelCluster;
603
604 cluster_map->erase(iter);
605 NewMerge = true;
606 goto REPEAT_LOOP;
607 }
608 }
609 }
610 REPEAT_LOOP: ;
611 }
612 }
613
614 return StatusCode::SUCCESS;
615}
616
617StatusCode
619{
621 "--- SiSmearedDigitizationTool: in mergeClusters() using SCT_Clusters ---");
622
623 if (!cluster_map) {
624 ATH_MSG_FATAL("Null SCT cluster map passed to mergeClusters()");
625 return StatusCode::FAILURE;
626 }
627
628 auto i = cluster_map->begin();
629
630 while (i != cluster_map->end()) {
631 const IdentifierHash current_id = i->first;
632 bool mergedThisPass;
633
634 do {
635 mergedThisPass = false;
636 const auto range = cluster_map->equal_range(current_id);
637
638 auto iter = range.first;
639 //coverity complains due to the erase; but there is a break immediately after
640 //coverity[INVALIDATE_ITERATOR]
641 while (iter != range.second && !mergedThisPass) {
642 auto inner_iter = std::next(iter);
643
644 while (inner_iter != range.second) {
645 const double dist =
646 calculateDistance(iter->second, inner_iter->second);
647 const double sigma =
648 calculateSigma(iter->second, inner_iter->second);
649
650 if (dist > m_nSigma * sigma) {
651 ++inner_iter;
652 continue;
653 }
654
656 InDet::SiWidth siWidth;
657 Amg::MatrixX clusterErr;
658
659 std::tie(intersection, siWidth, clusterErr) =
660 calculateNewCluster(iter->second, inner_iter->second);
661
662 const InDetDD::SiDetectorElement* hitSiDetElement =
663 inner_iter->second->detectorElement();
664
665 const Identifier intersectionId =
666 hitSiDetElement->identifierOfPosition(intersection);
667
668 const InDetDD::SiCellId currentCellId =
669 hitSiDetElement->cellIdFromIdentifier(intersectionId);
670
671 if (!currentCellId.isValid()) {
672 ++inner_iter;
673 continue;
674 }
675
676 std::vector<Identifier> rdoList{intersectionId};
677
678 auto sctCluster = std::make_unique<InDet::SCT_Cluster>(
679 intersectionId,
681 std::move(rdoList),
682 siWidth,
683 hitSiDetElement,
684 std::move(clusterErr));
685
686 auto* const oldIterCluster = iter->second;
687 auto* const oldInnerCluster = inner_iter->second;
688
689 inner_iter->second = sctCluster.release();
690
691 delete oldIterCluster;
692 delete oldInnerCluster;
693
694 cluster_map->erase(iter);
695
696 mergedThisPass = true;
697 break;
698 }
699
700 if (!mergedThisPass) {
701 ++iter;
702 }
703 }
704 } while (mergedThisPass);
705
706 i = cluster_map->upper_bound(current_id);
707 }
708
709 return StatusCode::SUCCESS;
710}
711StatusCode SiSmearedDigitizationTool::digitize(const EventContext& ctx,
713{
714 // Set the RNG to use for this event.
715 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
716 const std::string rngName = name()+m_randomEngineName;
717 rngWrapper->setSeed( rngName, ctx );
718 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
719
720 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SiSmearedDigizationTool::digitize() ---" );
721
722 // Get PixelDetectorElementCollection
723 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
724 if (m_SmearPixel) {
726 elementsPixel = pixelDetEle.retrieve();
727 if (elementsPixel==nullptr) {
728 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
729 return StatusCode::FAILURE;
730 }
731 }
732 // Get SCT_DetectorElementCollection
733 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
734 if (not m_SmearPixel) {
736 elementsSCT = sctDetEle.retrieve();
737 if (elementsSCT==nullptr) {
738 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
739 return StatusCode::FAILURE;
740 }
741 }
742
744
745 if(m_SmearPixel) { // Smear Pixel
747 } else {// Smear SCT
749 }
750
751 while (thpcsi.nextDetectorElement(i, e)) {
752
753 while (i != e) {
754 m_useDiscSurface = false;
755
756 const TimedHitPtr<SiHit>& hit(*i++);
757 int barrelEC = hit->getBarrelEndcap();
758 int layerDisk = hit->getLayerDisk();
759 int phiModule = hit->getPhiModule();
760 int etaModule = hit->getEtaModule();
761 int side = 0;
762
763 const InDetDD::SiDetectorElement* hitSiDetElement = nullptr;
764
765 if(m_SmearPixel) { // Smear Pixel
766 Identifier wafer_id = m_pixel_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule);
767 IdentifierHash wafer_hash = m_pixel_ID->wafer_hash(wafer_id);
768 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsPixel->getDetectorElement(wafer_hash);
769 ATH_MSG_DEBUG("Pixel SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule );
770 hitSiDetElement = hitSiDetElement_temp;
771 } else { // Smear SCT
772 side = hit->getSide();
773 Identifier idwafer = m_sct_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule,side);
774 IdentifierHash idhash = m_sct_ID->wafer_hash(m_sct_ID->wafer_id(idwafer));
775 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsSCT->getDetectorElement(idhash);
776 ATH_MSG_DEBUG("SCT SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule << ", side " << side);
777 hitSiDetElement = hitSiDetElement_temp;
778 }
779
780 // untangling the logic: if not using custom geometry, hitSiDetElement
781 // gets dereferenced (and should be checked)
782 //
783 // if using custom geometry, hitPlanarDetElement gets dereferenced
784 // (and should be checked)
785 if (not hitSiDetElement) {
786 ATH_MSG_FATAL("hitSiDetElement is null in SiSmearedDigitizationTool:"<<__LINE__);
787 throw std::runtime_error(std::string("hitSiDetElement is null in SiSmearedDigitizationTool::digitize() "));
788 }
789
790 if (m_SmearPixel && !(hitSiDetElement->isPixel())) continue;
791 if (!m_SmearPixel && !(hitSiDetElement->isSCT())) continue;
792
793 IdentifierHash waferID;
794
795 if(m_SmearPixel) { // Smear Pixel
796 waferID = m_pixel_ID->wafer_hash(hitSiDetElement->identify());
797 } else { // Smear SCT
798 waferID = m_sct_ID->wafer_hash(hitSiDetElement->identify());
799 }
800
801 HepGeom::Point3D<double> pix_localStartPosition = hit->localStartPosition();
802 HepGeom::Point3D<double> pix_localEndPosition = hit->localEndPosition();
803
804 pix_localStartPosition = hitSiDetElement->hitLocalToLocal3D(pix_localStartPosition);
805 pix_localEndPosition = hitSiDetElement->hitLocalToLocal3D(pix_localEndPosition);
806
807 double localEntryX = pix_localStartPosition.x();
808 double localEntryY = pix_localStartPosition.y();
809 double localEntryZ = pix_localStartPosition.z();
810 double localExitX = pix_localEndPosition.x();
811 double localExitY = pix_localEndPosition.y();
812 double localExitZ = pix_localEndPosition.z();
813
814 double thickness = 0.0;
815 thickness = hitSiDetElement->thickness();
816
817 // Transform to reconstruction local coordinates (different x,y,z ordering and sign conventions compared to simulation coords)
818 if (!m_SmearPixel) { // Smear SCT
819 HepGeom::Point3D<double> sct_localStartPosition = hit->localStartPosition();
820 HepGeom::Point3D<double> sct_localEndPosition = hit->localEndPosition();
821
822 sct_localStartPosition = hitSiDetElement->hitLocalToLocal3D(sct_localStartPosition);
823 sct_localEndPosition = hitSiDetElement->hitLocalToLocal3D(sct_localEndPosition);
824
825 localEntryX = sct_localStartPosition.x();
826 localEntryY = sct_localStartPosition.y();
827 localEntryZ = sct_localStartPosition.z();
828 localExitX = sct_localEndPosition.x();
829 localExitY = sct_localEndPosition.y();
830 localExitZ = sct_localEndPosition.z();
831 }
832
833 double distX = std::abs(std::abs(localExitX)-std::abs(localEntryX));
834 double distY = std::abs(std::abs(localExitY)-std::abs(localEntryY));
835
836 if(m_SmearPixel) { // Smear Pixel
837 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
838 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
839 m_x_entry_pixel = localEntryX;
840 m_y_entry_pixel = localEntryY;
841 m_z_entry_pixel = localEntryZ;
842 m_x_exit_pixel = localExitX;
843 m_y_exit_pixel = localExitY;
844 m_z_exit_pixel = localExitZ;
845 } else { // Smear SCT
846 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
847 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
848 m_x_entry_SCT = localEntryX;
849 m_y_entry_SCT = localEntryY;
850 m_z_entry_SCT = localEntryZ;
851 m_x_exit_SCT = localExitX;
852 m_y_exit_SCT = localExitY;
853 m_z_exit_SCT = localExitZ;
854 }
855
856 Amg::Vector2D localEntry(localEntryX,localEntryY);
857 Amg::Vector2D localExit(localExitX,localExitY);
858
859 // the pixel positions and other needed stuff for the geometrical clustering
860 std::vector<Identifier> rdoList;
861
862 Amg::Vector3D localDirection(localExitX-localEntryX, localExitY-localEntryY, localExitZ-localEntryZ);
863
864 InDetDD::SiCellId entryCellId;
865 InDetDD::SiCellId exitCellId;
866
867 // get the identifier of the entry and the exit
868 Identifier entryId = hitSiDetElement->identifierOfPosition(localEntry);
869 Identifier exitId = hitSiDetElement->identifierOfPosition(localExit);
870
871 // now get the cellIds and check whether they're valid
872 entryCellId = hitSiDetElement->cellIdFromIdentifier(entryId);
873 exitCellId = hitSiDetElement->cellIdFromIdentifier(exitId);
874
875 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryId " << entryId << " --- exitId " << exitId );
876 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryCellId " << entryCellId << " --- exitCellId " << exitCellId );
877
878 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: surface " << hitSiDetElement->surface());
879
880 // entry / exit validity
881 bool entryValid = entryCellId.isValid();
882 bool exitValid = exitCellId.isValid();
883
884 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryValid? " << entryValid << " --- exitValid? " << exitValid );
885
886 if (!entryValid && !exitValid) continue;
887
888 // the intersecetion id and cellId of it
889 double interX = 0.5*(localEntryX+localExitX);
890 double interY = 0.5*(localEntryY+localExitY);
891
892 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter X --- " << interX );
893 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter Y --- " << interY );
894 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist X --- " << distX );
895 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist Y --- " << distY );
896
897 //the particle crosses at least n pixels (in x direction you have timesX, in y direction you have timesY)
898 double timesX = (m_pitch_X) ? floor(distX/m_pitch_X) : 0;
899 double timesY = (m_pitch_Y) ? floor(distY/m_pitch_Y) : 0;
900
901 double newdistX = distX - (timesX*m_pitch_X);
902 double newdistY = distY - (timesY*m_pitch_Y);
903
904 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times X --- " << timesX );
905 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times Y --- " << timesY );
906 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist X --- " << newdistX );
907 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist Y --- " << newdistY );
908 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: thickness --- " << thickness );
909
910 //Probability
911
912 double ProbY = 2*newdistY/(m_pitch_Y+newdistY);
913 double ProbX = 2*newdistX/(m_pitch_X+newdistX);
914
915 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbX --- " << ProbX );
916 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbY --- " << ProbY );
917
918 // create the errors
919 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch X --- " << m_pitch_X );
920 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch Y --- " << m_pitch_Y );
921
922 double sigmaX = m_pitch_X/sqrt(12.);
923 double sigmaY = m_pitch_Y/sqrt(12.);
924
925 int elementX = timesX+1;
926 int elementY = timesY+1;
927
928 if(m_SmearPixel) {
929 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbY) { // number of crossed pixel is (timesY+1)+1
930 sigmaY = (double)(timesY+2)*m_pitch_Y/sqrt(12.);
931 elementY++;
932 } else // number of crossed pixel is (timesY+1)
933 sigmaY = (double)(timesY+1)*m_pitch_Y/sqrt(12.);
934
935 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbX) { // number of crossed pixel is (timesY+1)+1
936 sigmaX = (double)(timesX+2)*m_pitch_X/sqrt(12.);
937 elementX++;
938 } else // number of crossed pixel is (timesY+1)
939 sigmaX = (double)(timesX+1)*m_pitch_X/sqrt(12.);
940 }
941
942 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma X --- " << sigmaX);
943 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma Y --- " << sigmaY);
944
945
946 double temp_X = interX;
947 double temp_Y = interY;
948
949 Amg::Vector2D intersection(interX, interY);
950
951 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection after smearing: " << intersection);
952
953 Identifier intersectionId;
954 intersectionId = hitSiDetElement->identifierOfPosition(intersection);
955
956 rdoList.push_back(intersectionId);
957 InDetDD::SiCellId currentCellId = hitSiDetElement->cellIdFromIdentifier(intersectionId);
958
959 if (!currentCellId.isValid()) continue;
960
961 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection Id = " << intersectionId << " --- currentCellId = " << currentCellId );
962
963 if(m_SmearPixel) { // Smear Pixel --> Create Pixel Cluster
964
965 double lengthX = (m_pitch_X) ? elementX*m_pitch_X : 1.;
966 double lengthY = (m_pitch_Y) ? elementY*m_pitch_Y : 1.;
967
968 if (m_pitch_X == 0. || m_pitch_Y == 0.)
969 ATH_MSG_WARNING( "--- SiSmearedDigitizationTool: pitchX and/or pitchY are 0. Cluster length is forced to be 1. mm");
970
971 InDet::SiWidth siWidth(Amg::Vector2D(elementX,elementY), Amg::Vector2D(lengthX, lengthY));
972
973 InDet::PixelCluster* pixelCluster = nullptr;
974
975 AmgSymMatrix(2) covariance;
976 covariance.setIdentity();
977 covariance(Trk::locX,Trk::locX) = sigmaX*sigmaX;
978 covariance(Trk::locY,Trk::locY) = sigmaY*sigmaY;
979
980 // create the cluster
981 pixelCluster = new InDet::PixelCluster(intersectionId,
983 std::move(rdoList),
984 siWidth,
985 hitSiDetElement,
986 Amg::MatrixX(covariance));
987 m_pixelClusterMap->insert(std::pair<IdentifierHash, InDet::PixelCluster* >(waferID, pixelCluster));
988
989 if (FillTruthMap(m_pixelPrdTruth, pixelCluster, hit).isFailure()) {
990 ATH_MSG_FATAL ( "FillTruthMap() for pixel failed!" );
991 return StatusCode::FAILURE;
992 }
993
994 if (m_checkSmear) {
995
996 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixelCluster --> " << *pixelCluster);
997 //Take info to store in the tree
998 m_x_pixel = temp_X;
999 m_y_pixel = temp_Y;
1000
1001 m_x_pixel_smeared = (pixelCluster->localPosition()).x();
1002 m_y_pixel_smeared = (pixelCluster->localPosition()).y();
1003
1004 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_pixel << " Y = " << m_y_pixel);
1005 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_pixel_smeared << " Y = " << m_y_pixel_smeared);
1006
1007 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (pixelCluster->globalPosition()).x() << " Y = " << (pixelCluster->globalPosition()).y());
1008 m_x_pixel_global = (pixelCluster->globalPosition()).x();
1009 m_y_pixel_global = (pixelCluster->globalPosition()).y();
1010 m_z_pixel_global = (pixelCluster->globalPosition()).z();
1011
1012 m_Err_x_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locX);
1013 m_Err_y_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locY);
1014
1015 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Error --> X = " << m_Err_x_pixel << " Y = " << m_Err_y_pixel);
1016
1017 m_currentTree -> Fill();
1018 } // End of Pix smear check
1019
1020 } else { // Smear SCT --> Create SCT Cluster
1021
1022 // prepare the clusters
1023 InDet::SCT_Cluster * sctCluster = nullptr;
1024
1025 // Pixel Design needed -------------------------------------------------------------
1026 const InDetDD::SCT_ModuleSideDesign* design_sct;
1027
1028 design_sct = dynamic_cast<const InDetDD::SCT_ModuleSideDesign*>(&hitSiDetElement->design());
1029
1030 if (!design_sct) {
1031 ATH_MSG_INFO ( "Could not get design"<< design_sct) ;
1032 continue;
1033 }
1034
1035 // Find length of strip at centre
1036 double clusterWidth = rdoList.size()*hitSiDetElement->phiPitch(intersection);
1037 const std::pair<InDetDD::SiLocalPosition, InDetDD::SiLocalPosition> ends(design_sct->endsOfStrip(intersection));
1038 double stripLength = std::abs(ends.first.xEta()-ends.second.xEta());
1039
1040 InDet::SiWidth siWidth(Amg::Vector2D(int(rdoList.size()),1),
1041 Amg::Vector2D(clusterWidth,stripLength) );
1042
1043 const Amg::Vector2D& colRow = siWidth.colRow();
1044
1045 AmgSymMatrix(2) mat;
1046 mat.setIdentity();
1047 mat(Trk::locX,Trk::locX) = sigmaX*sigmaX;
1048 mat(Trk::locY,Trk::locY) = hitSiDetElement->length()*hitSiDetElement->length()/12.;
1049
1050 // single strip - resolution close to pitch/sqrt(12)
1051 // two-strip hits: better resolution, approx. 40% lower
1052
1053 InDetDD::DetectorShape elShape = hitSiDetElement->design().shape();
1054 if(m_emulateAtlas && elShape == InDetDD::Trapezoid)
1055 { // rotation for endcap SCT
1056
1057 if(colRow.x() == 1) {
1058 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1059 }
1060 else if(colRow.x() == 2) {
1061 mat(Trk::locX,Trk::locX) = pow(0.27*siWidth.phiR(),2)/12;
1062 }
1063 else {
1064 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1065 }
1066
1067 mat(Trk::locY,Trk::locY) = pow(siWidth.z()/colRow.y(),2)/12;
1068 double sn = hitSiDetElement->sinStereoLocal(intersection);
1069 double sn2 = sn*sn;
1070 double cs2 = 1.-sn2;
1071 double w = hitSiDetElement->phiPitch(intersection)/hitSiDetElement->phiPitch();
1072 double v0 = mat(Trk::locX, Trk::locX)*w*w;
1073 double v1 = mat(Trk::locY, Trk::locY);
1074 mat(Trk::locX, Trk::locX) = (cs2*v0+sn2*v1);
1075 mat(Trk::locY, Trk::locX) = (sn*sqrt(cs2)*(v0-v1));
1076 mat(Trk::locY, Trk::locY) = (sn2*v0+cs2*v1);
1077 } // End of rotation endcap SCT
1078
1079
1080 sctCluster = new InDet::SCT_Cluster(intersectionId,
1082 std::move(rdoList),
1083 siWidth,
1084 hitSiDetElement,
1085 Amg::MatrixX(mat));
1086
1087 m_sctClusterMap->insert(std::pair<IdentifierHash, InDet::SCT_Cluster* >(waferID, sctCluster));
1088
1089 if (FillTruthMap(m_SCTPrdTruth, sctCluster, hit).isFailure()) {
1090 ATH_MSG_FATAL ( "FillTruthMap() for SCT failed!" );
1091 return StatusCode::FAILURE;
1092 }
1093
1094 if (m_checkSmear) {
1095
1096 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT_Cluster --> " << *sctCluster);
1097
1098 //Take info to store in the tree
1099 m_x_SCT = m_useDiscSurface ? temp_Y : temp_X;
1100 m_x_SCT_smeared = (sctCluster->localPosition()).x();
1101
1102 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_SCT );
1103 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_SCT_smeared );
1104
1105 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (sctCluster->globalPosition()).x() << " Y = " << (sctCluster->globalPosition()).y());
1106 m_x_SCT_global = (sctCluster->globalPosition()).x();
1107 m_y_SCT_global = (sctCluster->globalPosition()).y();
1108 m_z_SCT_global = (sctCluster->globalPosition()).z();
1109
1110 m_currentTree -> Fill();
1111 } // End smear checking
1112 } // End SCT
1113 } // while
1114 } //while
1115 return StatusCode::SUCCESS;
1116}
1117
1118
1119StatusCode SiSmearedDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
1120{
1121 // Get PixelDetectorElementCollection
1122 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
1123 if (m_SmearPixel) {
1125 elementsPixel = pixelDetEle.retrieve();
1126 if (elementsPixel==nullptr) {
1127 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
1128 return StatusCode::FAILURE;
1129 }
1130 }
1131 // Get SCT_DetectorElementCollection
1132 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
1133 if (not m_SmearPixel) {
1135 elementsSCT = sctDetEle.retrieve();
1136 if (elementsSCT==nullptr) {
1137 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
1138 return StatusCode::FAILURE;
1139 }
1140 }
1141
1142 if ( m_SmearPixel ) { // Store Pixel RIOs
1143
1144 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel createAndStoreRIOs() ---" );
1145
1146 Pixel_detElement_RIO_map::iterator i = m_pixelClusterMap->begin();
1147 Pixel_detElement_RIO_map::iterator e = m_pixelClusterMap->end();
1148
1149 for ( ; i != e; i = m_pixelClusterMap->upper_bound(i->first) ) {
1150
1151 std::pair <Pixel_detElement_RIO_map::iterator, Pixel_detElement_RIO_map::iterator> range;
1152 range = m_pixelClusterMap->equal_range(i->first);
1153
1154 Pixel_detElement_RIO_map::iterator firstDetElem;
1155 firstDetElem = range.first;
1156
1157 IdentifierHash waferID;
1158 waferID = firstDetElem->first;
1159
1160 const InDetDD::SiDetectorElement* detElement = elementsPixel->getDetectorElement(waferID);
1161
1162 InDet::PixelClusterCollection *clusterCollection = new InDet::PixelClusterCollection(waferID);
1163 clusterCollection->setIdentifier(detElement->identify());
1164
1165 for ( Pixel_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1166
1167 InDet::PixelCluster* pixelCluster = (*iter).second;
1168 pixelCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1169 clusterCollection->push_back(pixelCluster);
1170 }
1171
1172 if ( m_pixelClusterContainer->addCollection( clusterCollection, waferID ).isFailure() ) {
1173 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1174 }
1175 } // end for
1176
1177 m_pixelClusterMap->clear();
1178
1179 }
1180 else { // Store SCT RIOs
1181
1182 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SCT createAndStoreRIOs() ---" );
1183
1184 SCT_detElement_RIO_map::iterator i = m_sctClusterMap->begin();
1185 SCT_detElement_RIO_map::iterator e = m_sctClusterMap->end();
1186
1187 for ( ; i != e; i = m_sctClusterMap->upper_bound(i->first) ) {
1188 std::pair <SCT_detElement_RIO_map::iterator, SCT_detElement_RIO_map::iterator> range;
1189 range = m_sctClusterMap->equal_range(i->first);
1190
1191 SCT_detElement_RIO_map::iterator firstDetElem;
1192 firstDetElem = range.first;
1193
1194 IdentifierHash waferID;
1195 waferID = firstDetElem->first;
1196 const InDetDD::SiDetectorElement* detElement = elementsSCT->getDetectorElement(waferID);
1197
1198 InDet::SCT_ClusterCollection *clusterCollection = new InDet::SCT_ClusterCollection(waferID);
1199 clusterCollection->setIdentifier(detElement->identify());
1200
1201
1202 for ( SCT_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1203 InDet::SCT_Cluster* sctCluster = (*iter).second;
1204 sctCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1205 clusterCollection->push_back(sctCluster);
1206 }
1207
1208 if ( m_sctClusterContainer->addCollection( clusterCollection, clusterCollection->identifyHash() ).isFailure() ) {
1209 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1210 }
1211
1212 } // end for
1213
1214 m_sctClusterMap->clear();
1215 }
1216
1217 return StatusCode::SUCCESS;
1218}
#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,...)
xAOD::CaloCluster CLUSTER
#define AmgSymMatrix(dim)
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
bool hit(const Container &ids, int pdgId)
the preferred mechanism to access information from the different event stores in a pileup job.
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
AtlasHitsVector< SiHit > SiHitCollection
std::tuple< Amg::Vector2D, InDet::SiWidth, Amg::MatrixX > ClusterInfo
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
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
size_type size() const
This is a "hash" representation of an Identifier.
virtual DetectorShape shape() const
Shape of element.
Base class for the SCT module side design, extended by the Forward and Barrel module design.
virtual std::pair< SiLocalPosition, SiLocalPosition > endsOfStrip(const SiLocalPosition &position) const override=0
give the ends of strips
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
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 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 Identifier identify() const override final
identifier of this detector element (inline)
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift).
Trk::Surface & surface()
Element Surface.
const Amg::Vector3D & globalPosition() const
return global position reference
double z() const
Definition SiWidth.h:131
double phiR() const
Definition SiWidth.h:126
const Amg::Vector2D & widthPhiRZ() const
Definition SiWidth.h:121
const Amg::Vector2D & colRow() const
Definition SiWidth.h:115
A PRD is mapped onto all contributing particles.
Gaudi::Property< int > m_vetoPileUpTruthLinks
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)
const_pointer_type retrieve()
Property holding a SG store/key/clid from which a WriteHandle is made.
std::string m_randomEngineName
Name of the random number stream.
const SCT_ID * m_sct_ID
Handle to the ID helper.
InDet::SCT_ClusterContainer * m_sctClusterContainer
the SCT_ClusterContainer
double calculateDistance(CLUSTER *clusterA, CLUSTER *clusterB)
StatusCode mergeClusters(Pixel_detElement_RIO_map *cluster_map)
StatusCode createAndStoreRIOs(const EventContext &ctx)
TTree * m_currentTree
the tree to store information from pixel and SCT (before and after smearing)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
SCT_detElement_RIO_map * m_sctClusterMap
std::multimap< IdentifierHash, InDet::SCT_Cluster * > SCT_detElement_RIO_map
const PixelID * m_pixel_ID
Handle to the ID helper.
StatusCode digitize(const EventContext &ctx, TimedHitCollection< SiHit > &thpcsi)
PRD_MultiTruthCollection * m_pixelPrdTruth
StatusCode processAllSubEvents(const EventContext &ctx)
ServiceHandle< PileUpMergeSvc > m_mergeSvc
PileUp Merge service.
std::multimap< IdentifierHash, InDet::PixelCluster * > Pixel_detElement_RIO_map
StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents)
StatusCode FillTruthMap(PRD_MultiTruthCollection *, CLUSTER *, const TimedHitPtr< SiHit > &)
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
ServiceHandle< ITHistSvc > m_thistSvc
ClusterInfo calculateNewCluster(CLUSTER *clusterA, CLUSTER *clusterB)
PRD_MultiTruthCollection * m_SCTPrdTruth
InDet::PixelClusterContainer * m_pixelClusterContainer
the PixelClusterContainer
std::vector< SiHitCollection * > m_siHitCollList
name of the sub event hit collections.
int m_HardScatterSplittingMode
Process all SiHit or just those from signal or background events.
StatusCode prepareEvent(const EventContext &ctx, unsigned int)
Pixel_detElement_RIO_map * m_pixelClusterMap
StatusCode mergeEvent(const EventContext &ctx)
double calculateSigma(CLUSTER *clusterA, CLUSTER *clusterB)
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
void insert(const PileUpTimeEventIndex &timeEventIndex, const AtlasHitsVector< HIT > *inputCollection)
a smart pointer to a hit that also provides access to the extended timing info of the host event.
Definition TimedHitPtr.h:18
const Amg::Vector2D & localPosition() const
return the local position reference
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
STL class.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
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.
Message Stream Member.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
index_type index() const
the index of the component event in PileUpEventInfo
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
time_type time() const
bunch xing time in ns