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 InDet::SiClusterContainer* symSiContainer=nullptr;
317
318 if(m_SmearPixel){ // Smear Pixel
319 m_pixelClusterContainer = new InDet::PixelClusterContainer(m_pixel_ID->wafer_hash_max());
320
322 ATH_MSG_FATAL( "[ --- ] Could not create PixelClusterContainer");
323 return StatusCode::FAILURE;
324 }
325
326 // --------------------------------------
327 // PixelCluster container registration
328
329 m_pixelClusterContainer->cleanup();
330 if ((evtStore()->record(m_pixelClusterContainer, m_pixel_SiClustersName)).isFailure()) {
331 if ((evtStore()->retrieve(m_pixelClusterContainer, m_pixel_SiClustersName)).isFailure()) {
332 ATH_MSG_FATAL("[ hitproc ] Error while registering PixelCluster container");
333 return StatusCode::FAILURE;
334 }
335 }
336
337 // symlink the Pixel Container
338 // Pixel
339
340 if ((evtStore()->symLink(m_pixelClusterContainer,symSiContainer)).isFailure()) {
341 ATH_MSG_FATAL( "[ --- ] PixelClusterContainer could not be symlinked to SiClusterContainter in StoreGate !" );
342 return StatusCode::FAILURE;
343 } else {
344 ATH_MSG_INFO( "[ hitproc ] PixelClusterContainer symlinked to SiClusterContainer in StoreGate" );
345 }
346
347 }else{ // Smear SCT
348 m_sctClusterContainer = new InDet::SCT_ClusterContainer(m_sct_ID->wafer_hash_max());
349
351 ATH_MSG_FATAL( "[ --- ] Could not create SCT_ClusterContainer");
352 return StatusCode::FAILURE;
353 }
354
355 // --------------------------------------
356 // SCT_Cluster container registration
357 m_sctClusterContainer->cleanup();
358 if ((evtStore()->record(m_sctClusterContainer, m_Sct_SiClustersName)).isFailure()) {
359 ATH_MSG_FATAL("[ hitproc ] Error while registering SCT_Cluster container");
360 return StatusCode::FAILURE;
361 }
362 // symlink the SCT Container
363 // SCT
364
365 if ((evtStore()->symLink(m_sctClusterContainer,symSiContainer)).isFailure()) {
366 ATH_MSG_FATAL( "[ --- ] SCT_ClusterContainer could not be symlinked to SiClusterContainter in StoreGate !" );
367 return StatusCode::FAILURE;
368 } else {
369 ATH_MSG_DEBUG( "[ hitproc ] SCT_ClusterContainer symlinked to SiClusterContainer in StoreGate" );
370 }
371
372 }
373
374 if (retrieveTruth().isFailure()) {
375 ATH_MSG_FATAL ( "retrieveTruth() failed!" );
376 return StatusCode::FAILURE;
377 }
378
379 // get the container(s)
381
383
384 //this is a list<pair<time_t, DataLink<SCTUncompressedHitCollection> > >
385 TimedHitCollList hitCollList;
386 unsigned int numberOfSimHits(0);
387 if ( !(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
388 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
389 return StatusCode::FAILURE;
390 } else {
391 ATH_MSG_DEBUG ( hitCollList.size() << " SiHitCollections with key " << m_inputObjectName << " found" );
392 }
393
394 // Define Hit Collection
395 TimedHitCollection<SiHit> thpcsi(numberOfSimHits);
396
397 //now merge all collections into one
398 TimedHitCollList::iterator iColl(hitCollList.begin());
399 TimedHitCollList::iterator endColl(hitCollList.end() );
400
402 // loop on the hit collections
403 while ( iColl != endColl ) {
405 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
407 const SiHitCollection* p_collection(iColl->second);
408 thpcsi.insert(iColl->first, p_collection);
409 ATH_MSG_DEBUG ( "SiHitCollection found with " << p_collection->size() << " hits" );
410 ++iColl;
411 }
412
413 // Process the Hits straw by straw: get the iterator pairs for given straw
414 if(this->digitize(ctx, thpcsi).isFailure()) {
415 ATH_MSG_FATAL ( "digitize method failed!" );
416 return StatusCode::FAILURE;
417 }
418
419 if (m_merge)
420 if(this->mergeEvent(ctx).isFailure()) {
421 ATH_MSG_FATAL ( "merge method failed!" );
422 return StatusCode::FAILURE;
423 }
424
425 if (createAndStoreRIOs(ctx).isFailure()) {
426 ATH_MSG_FATAL ( "createAndStoreRIOs() failed!" );
427 return StatusCode::FAILURE;
428 }
429 else {
430 ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
431 }
432
433 return StatusCode::SUCCESS;
434
435}
436
438
439
440 if(m_SmearPixel){ // Smear Pixel
441
443
445 if((evtStore()->retrieve(m_pixelPrdTruth, m_prdTruthNamePixel)).isFailure()){
446 ATH_MSG_FATAL("Could not retrieve collection " << m_prdTruthNamePixel);
447 return StatusCode::FAILURE;
448 }
449 }else{
450 if((evtStore()->record(m_pixelPrdTruth, m_prdTruthNamePixel)).isFailure()){
451 ATH_MSG_FATAL("Could not record collection " << m_prdTruthNamePixel);
452 return StatusCode::FAILURE;
453 }
454 }
455 }else{ // Smear SCT
457
459 if((evtStore()->retrieve(m_SCTPrdTruth, m_prdTruthNameSCT)).isFailure()){
460 ATH_MSG_FATAL("Could not retrieve collection " << m_prdTruthNameSCT);
461 return StatusCode::FAILURE;
462 }
463 }else{
464 if((evtStore()->record(m_SCTPrdTruth, m_prdTruthNameSCT)).isFailure()){
465 ATH_MSG_FATAL("Could not record collection " << m_prdTruthNameSCT);
466 return StatusCode::FAILURE;
467 }
468 }
469 }
470
471
472 return StatusCode::SUCCESS;
473
474}
475
476template<typename CLUSTER>
478
479 ATH_MSG_DEBUG("Truth map filling with cluster " << *cluster << " and link = " << hit->particleLink());
480 if (hit->particleLink().isValid()){
481 if (!HepMC::ignoreTruthLink(hit->particleLink(), m_vetoPileUpTruthLinks)) {
482 map->insert(std::make_pair(cluster->identify(), hit->particleLink()));
483 ATH_MSG_DEBUG("Truth map filled with cluster " << *cluster << " and link = " << hit->particleLink());
484 }
485 }else{
486 ATH_MSG_DEBUG("Particle link NOT valid!! Truth map NOT filled with cluster" << cluster << " and link = " << hit->particleLink());
487 }
488
489 return StatusCode::SUCCESS;
490}
491
492StatusCode SiSmearedDigitizationTool::mergeEvent(const EventContext& /*ctx*/){
493
494 if (m_SmearPixel)
496 else
498}
499
500template<typename CLUSTER>
502
503 // take needed information on the first clusters
504 Amg::Vector2D intersection_a = clusterA->localPosition();
505
506 // take needed information on the second clusters
507 Amg::Vector2D intersection_b = clusterB->localPosition();
508
509 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection_a = " << intersection_a);
510 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection_b = " << intersection_b);
511
512 double distX = intersection_a.x() - intersection_b.x();
513 double distY = intersection_a.y() - intersection_b.y();
514
515 return sqrt(distX*distX + distY*distY);
516}
517
518template<typename CLUSTER>
520 // take needed information on the first cluster
521 const Amg::MatrixX& clusterErr_a = clusterA->localCovariance();
522
523 // take needed information on the second clusters
524 const Amg::MatrixX& clusterErr_b = clusterB->localCovariance();
525
526 double sigmaX = sqrt(Amg::error(clusterErr_a,Trk::locX) * Amg::error(clusterErr_a,Trk::locX) +
527 Amg::error(clusterErr_b,Trk::locX) * Amg::error(clusterErr_b,Trk::locX));
528
529 double sigmaY = sqrt(Amg::error(clusterErr_a,Trk::locY) * Amg::error(clusterErr_a,Trk::locY) +
530 Amg::error(clusterErr_b,Trk::locY) * Amg::error(clusterErr_b,Trk::locY));
531
532 return sqrt(sigmaX*sigmaX + sigmaY*sigmaY);
533}
534
535template<typename CLUSTER>
537 // take needed information on the first clusters
538 Amg::Vector2D intersection_a = clusterA->localPosition();
539 const Amg::MatrixX& clusterErr_a = clusterA->localCovariance();
540
541 // take needed information on the second clusters
542 Amg::Vector2D intersection_b = clusterB->localPosition();
543 const Amg::MatrixX& clusterErr_b = clusterB->localCovariance();
544
545 double sigmaX = sqrt(Amg::error(clusterErr_a,Trk::locX) * Amg::error(clusterErr_a,Trk::locX) +
546 Amg::error(clusterErr_b,Trk::locX) * Amg::error(clusterErr_b,Trk::locX));
547
548 double sigmaY = sqrt(Amg::error(clusterErr_a,Trk::locY) * Amg::error(clusterErr_a,Trk::locY) +
549 Amg::error(clusterErr_b,Trk::locY) * Amg::error(clusterErr_b,Trk::locY));
550
551 double interX = 0.5*(intersection_a.x()+intersection_b.x());
552 double interY = 0.5*(intersection_a.y()+intersection_b.y());
553
554 Amg::Vector2D intersection(interX, interY);
555
556 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: intersection = " << intersection);
557
558 const InDet::SiWidth& siWidth_a = clusterA->width();
559 const InDet::SiWidth& siWidth_b = clusterB->width();
560
561 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth_a = " << siWidth_a);
562 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth_b = " << siWidth_b);
563
564 Amg::Vector2D colRow = siWidth_a.colRow() + siWidth_b.colRow();
565 Amg::Vector2D phiRz = siWidth_a.widthPhiRZ() + siWidth_b.widthPhiRZ();
566
567 InDet::SiWidth siWidth(colRow, phiRz);
568
569 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: siWidth = " << siWidth);
570
571 AmgSymMatrix(2) covariance;
572 covariance.setIdentity();
573 covariance(Trk::locX,Trk::locX) = sigmaX*sigmaX;
574 covariance(Trk::locY,Trk::locY) = sigmaY*sigmaY;
575 Amg::MatrixX clusterErr = covariance;
576
577 return ClusterInfo( intersection, siWidth, clusterErr );
578
579}
580
582{
583 // The idea is first to check how many cluster we have to merge and then merge them.
584 // The loop is done until there aren't any clusters to merge
585
586 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in mergeClusters() using PixelClusters --- ");
587
588 Pixel_detElement_RIO_map::iterator i = cluster_map->begin();
589 Pixel_detElement_RIO_map::iterator e = cluster_map->end();
590
591 for (; i != e; i = cluster_map->upper_bound(i->first)){
592 IdentifierHash current_id = i->first;
593 // Check if clusters with current_id have been already considered
594
595 bool NewMerge = true;
596
597 while (NewMerge) {
598 NewMerge = false;
599 std::pair <Pixel_detElement_RIO_map::iterator, Pixel_detElement_RIO_map::iterator> range = cluster_map->equal_range(current_id);
600
601 for ( Pixel_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter){
602 for (Pixel_detElement_RIO_map::iterator inner_iter = std::next(iter); inner_iter != range.second; ++inner_iter){
603
604 double dist = calculateDistance((*iter).second,(*inner_iter).second);
605 double sigma = calculateSigma((*iter).second,(*inner_iter).second);
606
607 if( dist <= m_nSigma * sigma) {
608
609 std::vector<Identifier> rdoList;
610
612 InDet::SiWidth siWidth;
613 Amg::MatrixX clusterErr;
614 std::tie( intersection, siWidth, clusterErr ) = calculateNewCluster( iter->second, inner_iter->second );
615
616 const InDetDD::SiDetectorElement* hitSiDetElement = (((*inner_iter).second)->detectorElement());
617 Identifier intersectionId = hitSiDetElement->identifierOfPosition(intersection);
618
619 rdoList.push_back(intersectionId);
620
621 InDetDD::SiCellId currentCellId = hitSiDetElement->cellIdFromIdentifier(intersectionId);
622
623 if ( !currentCellId.isValid() ) {
624 continue;
625 }
626
627 InDet::PixelCluster* pixelCluster = new InDet::PixelCluster(intersectionId,
629 std::move(rdoList),
630 siWidth,
631 hitSiDetElement,
632 std::move(clusterErr));
633 ((*inner_iter).second) = pixelCluster;
634
635 cluster_map->erase(iter);
636 NewMerge = true;
637 goto REPEAT_LOOP;
638 }
639 }
640 }
641 REPEAT_LOOP: ;
642 }
643 }
644
645 return StatusCode::SUCCESS;
646}
647
648StatusCode
650{
652 "--- SiSmearedDigitizationTool: in mergeClusters() using SCT_Clusters ---");
653
654 if (!cluster_map) {
655 ATH_MSG_FATAL("Null SCT cluster map passed to mergeClusters()");
656 return StatusCode::FAILURE;
657 }
658
659 auto i = cluster_map->begin();
660
661 while (i != cluster_map->end()) {
662 const IdentifierHash current_id = i->first;
663 bool mergedThisPass;
664
665 do {
666 mergedThisPass = false;
667 const auto range = cluster_map->equal_range(current_id);
668
669 auto iter = range.first;
670 //coverity complains due to the erase; but there is a break immediately after
671 //coverity[INVALIDATE_ITERATOR]
672 while (iter != range.second && !mergedThisPass) {
673 auto inner_iter = std::next(iter);
674
675 while (inner_iter != range.second) {
676 const double dist =
677 calculateDistance(iter->second, inner_iter->second);
678 const double sigma =
679 calculateSigma(iter->second, inner_iter->second);
680
681 if (dist > m_nSigma * sigma) {
682 ++inner_iter;
683 continue;
684 }
685
687 InDet::SiWidth siWidth;
688 Amg::MatrixX clusterErr;
689
690 std::tie(intersection, siWidth, clusterErr) =
691 calculateNewCluster(iter->second, inner_iter->second);
692
693 const InDetDD::SiDetectorElement* hitSiDetElement =
694 inner_iter->second->detectorElement();
695
696 const Identifier intersectionId =
697 hitSiDetElement->identifierOfPosition(intersection);
698
699 const InDetDD::SiCellId currentCellId =
700 hitSiDetElement->cellIdFromIdentifier(intersectionId);
701
702 if (!currentCellId.isValid()) {
703 ++inner_iter;
704 continue;
705 }
706
707 std::vector<Identifier> rdoList{intersectionId};
708
709 auto sctCluster = std::make_unique<InDet::SCT_Cluster>(
710 intersectionId,
712 std::move(rdoList),
713 siWidth,
714 hitSiDetElement,
715 std::move(clusterErr));
716
717 auto* const oldIterCluster = iter->second;
718 auto* const oldInnerCluster = inner_iter->second;
719
720 inner_iter->second = sctCluster.release();
721
722 delete oldIterCluster;
723 delete oldInnerCluster;
724
725 cluster_map->erase(iter);
726
727 mergedThisPass = true;
728 break;
729 }
730
731 if (!mergedThisPass) {
732 ++iter;
733 }
734 }
735 } while (mergedThisPass);
736
737 i = cluster_map->upper_bound(current_id);
738 }
739
740 return StatusCode::SUCCESS;
741}
742StatusCode SiSmearedDigitizationTool::digitize(const EventContext& ctx,
744{
745 // Set the RNG to use for this event.
746 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
747 const std::string rngName = name()+m_randomEngineName;
748 rngWrapper->setSeed( rngName, ctx );
749 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
750
751 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SiSmearedDigizationTool::digitize() ---" );
752
753 // Get PixelDetectorElementCollection
754 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
755 if (m_SmearPixel) {
757 elementsPixel = pixelDetEle.retrieve();
758 if (elementsPixel==nullptr) {
759 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
760 return StatusCode::FAILURE;
761 }
762 }
763 // Get SCT_DetectorElementCollection
764 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
765 if (not m_SmearPixel) {
767 elementsSCT = sctDetEle.retrieve();
768 if (elementsSCT==nullptr) {
769 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
770 return StatusCode::FAILURE;
771 }
772 }
773
775
776 if(m_SmearPixel) { // Smear Pixel
778 } else {// Smear SCT
780 }
781
782 while (thpcsi.nextDetectorElement(i, e)) {
783
784 while (i != e) {
785 m_useDiscSurface = false;
786
787 const TimedHitPtr<SiHit>& hit(*i++);
788 int barrelEC = hit->getBarrelEndcap();
789 int layerDisk = hit->getLayerDisk();
790 int phiModule = hit->getPhiModule();
791 int etaModule = hit->getEtaModule();
792 int side = 0;
793
794 const InDetDD::SiDetectorElement* hitSiDetElement = nullptr;
795
796 if(m_SmearPixel) { // Smear Pixel
797 Identifier wafer_id = m_pixel_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule);
798 IdentifierHash wafer_hash = m_pixel_ID->wafer_hash(wafer_id);
799 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsPixel->getDetectorElement(wafer_hash);
800 ATH_MSG_DEBUG("Pixel SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule );
801 hitSiDetElement = hitSiDetElement_temp;
802 } else { // Smear SCT
803 side = hit->getSide();
804 Identifier idwafer = m_sct_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule,side);
805 IdentifierHash idhash = m_sct_ID->wafer_hash(m_sct_ID->wafer_id(idwafer));
806 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsSCT->getDetectorElement(idhash);
807 ATH_MSG_DEBUG("SCT SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule << ", side " << side);
808 hitSiDetElement = hitSiDetElement_temp;
809 }
810
811 // untangling the logic: if not using custom geometry, hitSiDetElement
812 // gets dereferenced (and should be checked)
813 //
814 // if using custom geometry, hitPlanarDetElement gets dereferenced
815 // (and should be checked)
816 if (not hitSiDetElement) {
817 ATH_MSG_FATAL("hitSiDetElement is null in SiSmearedDigitizationTool:"<<__LINE__);
818 throw std::runtime_error(std::string("hitSiDetElement is null in SiSmearedDigitizationTool::digitize() "));
819 }
820
821 if (m_SmearPixel && !(hitSiDetElement->isPixel())) continue;
822 if (!m_SmearPixel && !(hitSiDetElement->isSCT())) continue;
823
824 IdentifierHash waferID;
825
826 if(m_SmearPixel) { // Smear Pixel
827 waferID = m_pixel_ID->wafer_hash(hitSiDetElement->identify());
828 } else { // Smear SCT
829 waferID = m_sct_ID->wafer_hash(hitSiDetElement->identify());
830 }
831
832 HepGeom::Point3D<double> pix_localStartPosition = hit->localStartPosition();
833 HepGeom::Point3D<double> pix_localEndPosition = hit->localEndPosition();
834
835 pix_localStartPosition = hitSiDetElement->hitLocalToLocal3D(pix_localStartPosition);
836 pix_localEndPosition = hitSiDetElement->hitLocalToLocal3D(pix_localEndPosition);
837
838 double localEntryX = pix_localStartPosition.x();
839 double localEntryY = pix_localStartPosition.y();
840 double localEntryZ = pix_localStartPosition.z();
841 double localExitX = pix_localEndPosition.x();
842 double localExitY = pix_localEndPosition.y();
843 double localExitZ = pix_localEndPosition.z();
844
845 double thickness = 0.0;
846 thickness = hitSiDetElement->thickness();
847
848 // Transform to reconstruction local coordinates (different x,y,z ordering and sign conventions compared to simulation coords)
849 if (!m_SmearPixel) { // Smear SCT
850 HepGeom::Point3D<double> sct_localStartPosition = hit->localStartPosition();
851 HepGeom::Point3D<double> sct_localEndPosition = hit->localEndPosition();
852
853 sct_localStartPosition = hitSiDetElement->hitLocalToLocal3D(sct_localStartPosition);
854 sct_localEndPosition = hitSiDetElement->hitLocalToLocal3D(sct_localEndPosition);
855
856 localEntryX = sct_localStartPosition.x();
857 localEntryY = sct_localStartPosition.y();
858 localEntryZ = sct_localStartPosition.z();
859 localExitX = sct_localEndPosition.x();
860 localExitY = sct_localEndPosition.y();
861 localExitZ = sct_localEndPosition.z();
862 }
863
864 double distX = std::abs(std::abs(localExitX)-std::abs(localEntryX));
865 double distY = std::abs(std::abs(localExitY)-std::abs(localEntryY));
866
867 if(m_SmearPixel) { // Smear Pixel
868 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
869 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
870 m_x_entry_pixel = localEntryX;
871 m_y_entry_pixel = localEntryY;
872 m_z_entry_pixel = localEntryZ;
873 m_x_exit_pixel = localExitX;
874 m_y_exit_pixel = localExitY;
875 m_z_exit_pixel = localExitZ;
876 } else { // Smear SCT
877 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
878 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
879 m_x_entry_SCT = localEntryX;
880 m_y_entry_SCT = localEntryY;
881 m_z_entry_SCT = localEntryZ;
882 m_x_exit_SCT = localExitX;
883 m_y_exit_SCT = localExitY;
884 m_z_exit_SCT = localExitZ;
885 }
886
887 Amg::Vector2D localEntry(localEntryX,localEntryY);
888 Amg::Vector2D localExit(localExitX,localExitY);
889
890 // the pixel positions and other needed stuff for the geometrical clustering
891 std::vector<Identifier> rdoList;
892
893 Amg::Vector3D localDirection(localExitX-localEntryX, localExitY-localEntryY, localExitZ-localEntryZ);
894
895 InDetDD::SiCellId entryCellId;
896 InDetDD::SiCellId exitCellId;
897
898 // get the identifier of the entry and the exit
899 Identifier entryId = hitSiDetElement->identifierOfPosition(localEntry);
900 Identifier exitId = hitSiDetElement->identifierOfPosition(localExit);
901
902 // now get the cellIds and check whether they're valid
903 entryCellId = hitSiDetElement->cellIdFromIdentifier(entryId);
904 exitCellId = hitSiDetElement->cellIdFromIdentifier(exitId);
905
906 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryId " << entryId << " --- exitId " << exitId );
907 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryCellId " << entryCellId << " --- exitCellId " << exitCellId );
908
909 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: surface " << hitSiDetElement->surface());
910
911 // entry / exit validity
912 bool entryValid = entryCellId.isValid();
913 bool exitValid = exitCellId.isValid();
914
915 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryValid? " << entryValid << " --- exitValid? " << exitValid );
916
917 if (!entryValid && !exitValid) continue;
918
919 // the intersecetion id and cellId of it
920 double interX = 0.5*(localEntryX+localExitX);
921 double interY = 0.5*(localEntryY+localExitY);
922
923 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter X --- " << interX );
924 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter Y --- " << interY );
925 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist X --- " << distX );
926 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist Y --- " << distY );
927
928 //the particle crosses at least n pixels (in x direction you have timesX, in y direction you have timesY)
929 double timesX = (m_pitch_X) ? floor(distX/m_pitch_X) : 0;
930 double timesY = (m_pitch_Y) ? floor(distY/m_pitch_Y) : 0;
931
932 double newdistX = distX - (timesX*m_pitch_X);
933 double newdistY = distY - (timesY*m_pitch_Y);
934
935 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times X --- " << timesX );
936 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times Y --- " << timesY );
937 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist X --- " << newdistX );
938 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist Y --- " << newdistY );
939 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: thickness --- " << thickness );
940
941 //Probability
942
943 double ProbY = 2*newdistY/(m_pitch_Y+newdistY);
944 double ProbX = 2*newdistX/(m_pitch_X+newdistX);
945
946 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbX --- " << ProbX );
947 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbY --- " << ProbY );
948
949 // create the errors
950 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch X --- " << m_pitch_X );
951 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch Y --- " << m_pitch_Y );
952
953 double sigmaX = m_pitch_X/sqrt(12.);
954 double sigmaY = m_pitch_Y/sqrt(12.);
955
956 int elementX = timesX+1;
957 int elementY = timesY+1;
958
959 if(m_SmearPixel) {
960 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbY) { // number of crossed pixel is (timesY+1)+1
961 sigmaY = (double)(timesY+2)*m_pitch_Y/sqrt(12.);
962 elementY++;
963 } else // number of crossed pixel is (timesY+1)
964 sigmaY = (double)(timesY+1)*m_pitch_Y/sqrt(12.);
965
966 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbX) { // number of crossed pixel is (timesY+1)+1
967 sigmaX = (double)(timesX+2)*m_pitch_X/sqrt(12.);
968 elementX++;
969 } else // number of crossed pixel is (timesY+1)
970 sigmaX = (double)(timesX+1)*m_pitch_X/sqrt(12.);
971 }
972
973 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma X --- " << sigmaX);
974 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma Y --- " << sigmaY);
975
976
977 double temp_X = interX;
978 double temp_Y = interY;
979
980 Amg::Vector2D intersection(interX, interY);
981
982 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection after smearing: " << intersection);
983
984 Identifier intersectionId;
985 intersectionId = hitSiDetElement->identifierOfPosition(intersection);
986
987 rdoList.push_back(intersectionId);
988 InDetDD::SiCellId currentCellId = hitSiDetElement->cellIdFromIdentifier(intersectionId);
989
990 if (!currentCellId.isValid()) continue;
991
992 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection Id = " << intersectionId << " --- currentCellId = " << currentCellId );
993
994 if(m_SmearPixel) { // Smear Pixel --> Create Pixel Cluster
995
996 double lengthX = (m_pitch_X) ? elementX*m_pitch_X : 1.;
997 double lengthY = (m_pitch_Y) ? elementY*m_pitch_Y : 1.;
998
999 if (m_pitch_X == 0. || m_pitch_Y == 0.)
1000 ATH_MSG_WARNING( "--- SiSmearedDigitizationTool: pitchX and/or pitchY are 0. Cluster length is forced to be 1. mm");
1001
1002 InDet::SiWidth siWidth(Amg::Vector2D(elementX,elementY), Amg::Vector2D(lengthX, lengthY));
1003
1004 InDet::PixelCluster* pixelCluster = nullptr;
1005
1006 AmgSymMatrix(2) covariance;
1007 covariance.setIdentity();
1008 covariance(Trk::locX,Trk::locX) = sigmaX*sigmaX;
1009 covariance(Trk::locY,Trk::locY) = sigmaY*sigmaY;
1010
1011 // create the cluster
1012 pixelCluster = new InDet::PixelCluster(intersectionId,
1014 std::move(rdoList),
1015 siWidth,
1016 hitSiDetElement,
1017 Amg::MatrixX(covariance));
1018 m_pixelClusterMap->insert(std::pair<IdentifierHash, InDet::PixelCluster* >(waferID, pixelCluster));
1019
1020 if (FillTruthMap(m_pixelPrdTruth, pixelCluster, hit).isFailure()) {
1021 ATH_MSG_FATAL ( "FillTruthMap() for pixel failed!" );
1022 return StatusCode::FAILURE;
1023 }
1024
1025 if (m_checkSmear) {
1026
1027 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixelCluster --> " << *pixelCluster);
1028 //Take info to store in the tree
1029 m_x_pixel = temp_X;
1030 m_y_pixel = temp_Y;
1031
1032 m_x_pixel_smeared = (pixelCluster->localPosition()).x();
1033 m_y_pixel_smeared = (pixelCluster->localPosition()).y();
1034
1035 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_pixel << " Y = " << m_y_pixel);
1036 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_pixel_smeared << " Y = " << m_y_pixel_smeared);
1037
1038 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (pixelCluster->globalPosition()).x() << " Y = " << (pixelCluster->globalPosition()).y());
1039 m_x_pixel_global = (pixelCluster->globalPosition()).x();
1040 m_y_pixel_global = (pixelCluster->globalPosition()).y();
1041 m_z_pixel_global = (pixelCluster->globalPosition()).z();
1042
1043 m_Err_x_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locX);
1044 m_Err_y_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locY);
1045
1046 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Error --> X = " << m_Err_x_pixel << " Y = " << m_Err_y_pixel);
1047
1048 m_currentTree -> Fill();
1049 } // End of Pix smear check
1050
1051 } else { // Smear SCT --> Create SCT Cluster
1052
1053 // prepare the clusters
1054 InDet::SCT_Cluster * sctCluster = nullptr;
1055
1056 // Pixel Design needed -------------------------------------------------------------
1057 const InDetDD::SCT_ModuleSideDesign* design_sct;
1058
1059 design_sct = dynamic_cast<const InDetDD::SCT_ModuleSideDesign*>(&hitSiDetElement->design());
1060
1061 if (!design_sct) {
1062 ATH_MSG_INFO ( "Could not get design"<< design_sct) ;
1063 continue;
1064 }
1065
1066 // Find length of strip at centre
1067 double clusterWidth = rdoList.size()*hitSiDetElement->phiPitch(intersection);
1068 const std::pair<InDetDD::SiLocalPosition, InDetDD::SiLocalPosition> ends(design_sct->endsOfStrip(intersection));
1069 double stripLength = std::abs(ends.first.xEta()-ends.second.xEta());
1070
1071 InDet::SiWidth siWidth(Amg::Vector2D(int(rdoList.size()),1),
1072 Amg::Vector2D(clusterWidth,stripLength) );
1073
1074 const Amg::Vector2D& colRow = siWidth.colRow();
1075
1076 AmgSymMatrix(2) mat;
1077 mat.setIdentity();
1078 mat(Trk::locX,Trk::locX) = sigmaX*sigmaX;
1079 mat(Trk::locY,Trk::locY) = hitSiDetElement->length()*hitSiDetElement->length()/12.;
1080
1081 // single strip - resolution close to pitch/sqrt(12)
1082 // two-strip hits: better resolution, approx. 40% lower
1083
1084 InDetDD::DetectorShape elShape = hitSiDetElement->design().shape();
1085 if(m_emulateAtlas && elShape == InDetDD::Trapezoid)
1086 { // rotation for endcap SCT
1087
1088 if(colRow.x() == 1) {
1089 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1090 }
1091 else if(colRow.x() == 2) {
1092 mat(Trk::locX,Trk::locX) = pow(0.27*siWidth.phiR(),2)/12;
1093 }
1094 else {
1095 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1096 }
1097
1098 mat(Trk::locY,Trk::locY) = pow(siWidth.z()/colRow.y(),2)/12;
1099 double sn = hitSiDetElement->sinStereoLocal(intersection);
1100 double sn2 = sn*sn;
1101 double cs2 = 1.-sn2;
1102 double w = hitSiDetElement->phiPitch(intersection)/hitSiDetElement->phiPitch();
1103 double v0 = mat(Trk::locX, Trk::locX)*w*w;
1104 double v1 = mat(Trk::locY, Trk::locY);
1105 mat(Trk::locX, Trk::locX) = (cs2*v0+sn2*v1);
1106 mat(Trk::locY, Trk::locX) = (sn*sqrt(cs2)*(v0-v1));
1107 mat(Trk::locY, Trk::locY) = (sn2*v0+cs2*v1);
1108 } // End of rotation endcap SCT
1109
1110
1111 sctCluster = new InDet::SCT_Cluster(intersectionId,
1113 std::move(rdoList),
1114 siWidth,
1115 hitSiDetElement,
1116 Amg::MatrixX(mat));
1117
1118 m_sctClusterMap->insert(std::pair<IdentifierHash, InDet::SCT_Cluster* >(waferID, sctCluster));
1119
1120 if (FillTruthMap(m_SCTPrdTruth, sctCluster, hit).isFailure()) {
1121 ATH_MSG_FATAL ( "FillTruthMap() for SCT failed!" );
1122 return StatusCode::FAILURE;
1123 }
1124
1125 if (m_checkSmear) {
1126
1127 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT_Cluster --> " << *sctCluster);
1128
1129 //Take info to store in the tree
1130 m_x_SCT = m_useDiscSurface ? temp_Y : temp_X;
1131 m_x_SCT_smeared = (sctCluster->localPosition()).x();
1132
1133 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_SCT );
1134 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_SCT_smeared );
1135
1136 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (sctCluster->globalPosition()).x() << " Y = " << (sctCluster->globalPosition()).y());
1137 m_x_SCT_global = (sctCluster->globalPosition()).x();
1138 m_y_SCT_global = (sctCluster->globalPosition()).y();
1139 m_z_SCT_global = (sctCluster->globalPosition()).z();
1140
1141 m_currentTree -> Fill();
1142 } // End smear checking
1143 } // End SCT
1144 } // while
1145 } //while
1146 return StatusCode::SUCCESS;
1147}
1148
1149
1150StatusCode SiSmearedDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
1151{
1152 // Get PixelDetectorElementCollection
1153 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
1154 if (m_SmearPixel) {
1156 elementsPixel = pixelDetEle.retrieve();
1157 if (elementsPixel==nullptr) {
1158 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
1159 return StatusCode::FAILURE;
1160 }
1161 }
1162 // Get SCT_DetectorElementCollection
1163 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
1164 if (not m_SmearPixel) {
1166 elementsSCT = sctDetEle.retrieve();
1167 if (elementsSCT==nullptr) {
1168 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
1169 return StatusCode::FAILURE;
1170 }
1171 }
1172
1173 if ( m_SmearPixel ) { // Store Pixel RIOs
1174
1175 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel createAndStoreRIOs() ---" );
1176
1177 Pixel_detElement_RIO_map::iterator i = m_pixelClusterMap->begin();
1178 Pixel_detElement_RIO_map::iterator e = m_pixelClusterMap->end();
1179
1180 for ( ; i != e; i = m_pixelClusterMap->upper_bound(i->first) ) {
1181
1182 std::pair <Pixel_detElement_RIO_map::iterator, Pixel_detElement_RIO_map::iterator> range;
1183 range = m_pixelClusterMap->equal_range(i->first);
1184
1185 Pixel_detElement_RIO_map::iterator firstDetElem;
1186 firstDetElem = range.first;
1187
1188 IdentifierHash waferID;
1189 waferID = firstDetElem->first;
1190
1191 const InDetDD::SiDetectorElement* detElement = elementsPixel->getDetectorElement(waferID);
1192
1193 InDet::PixelClusterCollection *clusterCollection = new InDet::PixelClusterCollection(waferID);
1194 clusterCollection->setIdentifier(detElement->identify());
1195
1196 for ( Pixel_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1197
1198 InDet::PixelCluster* pixelCluster = (*iter).second;
1199 pixelCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1200 clusterCollection->push_back(pixelCluster);
1201 }
1202
1203 if ( m_pixelClusterContainer->addCollection( clusterCollection, waferID ).isFailure() ) {
1204 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1205 }
1206 } // end for
1207
1208 m_pixelClusterMap->clear();
1209
1210 }
1211 else { // Store SCT RIOs
1212
1213 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SCT createAndStoreRIOs() ---" );
1214
1215 SCT_detElement_RIO_map::iterator i = m_sctClusterMap->begin();
1216 SCT_detElement_RIO_map::iterator e = m_sctClusterMap->end();
1217
1218 for ( ; i != e; i = m_sctClusterMap->upper_bound(i->first) ) {
1219 std::pair <SCT_detElement_RIO_map::iterator, SCT_detElement_RIO_map::iterator> range;
1220 range = m_sctClusterMap->equal_range(i->first);
1221
1222 SCT_detElement_RIO_map::iterator firstDetElem;
1223 firstDetElem = range.first;
1224
1225 IdentifierHash waferID;
1226 waferID = firstDetElem->first;
1227 const InDetDD::SiDetectorElement* detElement = elementsSCT->getDetectorElement(waferID);
1228
1229 InDet::SCT_ClusterCollection *clusterCollection = new InDet::SCT_ClusterCollection(waferID);
1230 clusterCollection->setIdentifier(detElement->identify());
1231
1232
1233 for ( SCT_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1234 InDet::SCT_Cluster* sctCluster = (*iter).second;
1235 sctCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1236 clusterCollection->push_back(sctCluster);
1237 }
1238
1239 if ( m_sctClusterContainer->addCollection( clusterCollection, clusterCollection->identifyHash() ).isFailure() ) {
1240 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1241 }
1242
1243 } // end for
1244
1245 m_sctClusterMap->clear();
1246 }
1247
1248 return StatusCode::SUCCESS;
1249}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(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()
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