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
671 while (iter != range.second && !mergedThisPass) {
672 auto inner_iter = std::next(iter);
673
674 while (inner_iter != range.second) {
675 const double dist =
676 calculateDistance(iter->second, inner_iter->second);
677 const double sigma =
678 calculateSigma(iter->second, inner_iter->second);
679
680 if (dist > m_nSigma * sigma) {
681 ++inner_iter;
682 continue;
683 }
684
686 InDet::SiWidth siWidth;
687 Amg::MatrixX clusterErr;
688
689 std::tie(intersection, siWidth, clusterErr) =
690 calculateNewCluster(iter->second, inner_iter->second);
691
692 const InDetDD::SiDetectorElement* hitSiDetElement =
693 inner_iter->second->detectorElement();
694
695 const Identifier intersectionId =
696 hitSiDetElement->identifierOfPosition(intersection);
697
698 const InDetDD::SiCellId currentCellId =
699 hitSiDetElement->cellIdFromIdentifier(intersectionId);
700
701 if (!currentCellId.isValid()) {
702 ++inner_iter;
703 continue;
704 }
705
706 std::vector<Identifier> rdoList{intersectionId};
707
708 auto sctCluster = std::make_unique<InDet::SCT_Cluster>(
709 intersectionId,
711 std::move(rdoList),
712 siWidth,
713 hitSiDetElement,
714 std::move(clusterErr));
715
716 auto* const oldIterCluster = iter->second;
717 auto* const oldInnerCluster = inner_iter->second;
718
719 inner_iter->second = sctCluster.release();
720
721 delete oldIterCluster;
722 delete oldInnerCluster;
723
724 cluster_map->erase(iter);
725
726 mergedThisPass = true;
727 break;
728 }
729
730 if (!mergedThisPass) {
731 ++iter;
732 }
733 }
734 } while (mergedThisPass);
735
736 i = cluster_map->upper_bound(current_id);
737 }
738
739 return StatusCode::SUCCESS;
740}
741StatusCode SiSmearedDigitizationTool::digitize(const EventContext& ctx,
743{
744 // Set the RNG to use for this event.
745 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
746 const std::string rngName = name()+m_randomEngineName;
747 rngWrapper->setSeed( rngName, ctx );
748 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
749
750 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SiSmearedDigizationTool::digitize() ---" );
751
752 // Get PixelDetectorElementCollection
753 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
754 if (m_SmearPixel) {
756 elementsPixel = pixelDetEle.retrieve();
757 if (elementsPixel==nullptr) {
758 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
759 return StatusCode::FAILURE;
760 }
761 }
762 // Get SCT_DetectorElementCollection
763 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
764 if (not m_SmearPixel) {
766 elementsSCT = sctDetEle.retrieve();
767 if (elementsSCT==nullptr) {
768 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
769 return StatusCode::FAILURE;
770 }
771 }
772
774
775 if(m_SmearPixel) { // Smear Pixel
777 } else {// Smear SCT
779 }
780
781 while (thpcsi.nextDetectorElement(i, e)) {
782
783 while (i != e) {
784 m_useDiscSurface = false;
785
786 const TimedHitPtr<SiHit>& hit(*i++);
787 int barrelEC = hit->getBarrelEndcap();
788 int layerDisk = hit->getLayerDisk();
789 int phiModule = hit->getPhiModule();
790 int etaModule = hit->getEtaModule();
791 int side = 0;
792
793 const InDetDD::SiDetectorElement* hitSiDetElement = nullptr;
794
795 if(m_SmearPixel) { // Smear Pixel
796 Identifier wafer_id = m_pixel_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule);
797 IdentifierHash wafer_hash = m_pixel_ID->wafer_hash(wafer_id);
798 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsPixel->getDetectorElement(wafer_hash);
799 ATH_MSG_DEBUG("Pixel SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule );
800 hitSiDetElement = hitSiDetElement_temp;
801 } else { // Smear SCT
802 side = hit->getSide();
803 Identifier idwafer = m_sct_ID->wafer_id(barrelEC,layerDisk,phiModule,etaModule,side);
804 IdentifierHash idhash = m_sct_ID->wafer_hash(m_sct_ID->wafer_id(idwafer));
805 const InDetDD::SiDetectorElement* hitSiDetElement_temp = elementsSCT->getDetectorElement(idhash);
806 ATH_MSG_DEBUG("SCT SiDetectorElement --> barrel_ec " << barrelEC << ", layer_disk " << layerDisk << ", phi_module " << phiModule << ", eta_module " << etaModule << ", side " << side);
807 hitSiDetElement = hitSiDetElement_temp;
808 }
809
810 // untangling the logic: if not using custom geometry, hitSiDetElement
811 // gets dereferenced (and should be checked)
812 //
813 // if using custom geometry, hitPlanarDetElement gets dereferenced
814 // (and should be checked)
815 if (not hitSiDetElement) {
816 ATH_MSG_FATAL("hitSiDetElement is null in SiSmearedDigitizationTool:"<<__LINE__);
817 throw std::runtime_error(std::string("hitSiDetElement is null in SiSmearedDigitizationTool::digitize() "));
818 }
819
820 if (m_SmearPixel && !(hitSiDetElement->isPixel())) continue;
821 if (!m_SmearPixel && !(hitSiDetElement->isSCT())) continue;
822
823 IdentifierHash waferID;
824
825 if(m_SmearPixel) { // Smear Pixel
826 waferID = m_pixel_ID->wafer_hash(hitSiDetElement->identify());
827 } else { // Smear SCT
828 waferID = m_sct_ID->wafer_hash(hitSiDetElement->identify());
829 }
830
831 HepGeom::Point3D<double> pix_localStartPosition = hit->localStartPosition();
832 HepGeom::Point3D<double> pix_localEndPosition = hit->localEndPosition();
833
834 pix_localStartPosition = hitSiDetElement->hitLocalToLocal3D(pix_localStartPosition);
835 pix_localEndPosition = hitSiDetElement->hitLocalToLocal3D(pix_localEndPosition);
836
837 double localEntryX = pix_localStartPosition.x();
838 double localEntryY = pix_localStartPosition.y();
839 double localEntryZ = pix_localStartPosition.z();
840 double localExitX = pix_localEndPosition.x();
841 double localExitY = pix_localEndPosition.y();
842 double localExitZ = pix_localEndPosition.z();
843
844 double thickness = 0.0;
845 thickness = hitSiDetElement->thickness();
846
847 // Transform to reconstruction local coordinates (different x,y,z ordering and sign conventions compared to simulation coords)
848 if (!m_SmearPixel) { // Smear SCT
849 HepGeom::Point3D<double> sct_localStartPosition = hit->localStartPosition();
850 HepGeom::Point3D<double> sct_localEndPosition = hit->localEndPosition();
851
852 sct_localStartPosition = hitSiDetElement->hitLocalToLocal3D(sct_localStartPosition);
853 sct_localEndPosition = hitSiDetElement->hitLocalToLocal3D(sct_localEndPosition);
854
855 localEntryX = sct_localStartPosition.x();
856 localEntryY = sct_localStartPosition.y();
857 localEntryZ = sct_localStartPosition.z();
858 localExitX = sct_localEndPosition.x();
859 localExitY = sct_localEndPosition.y();
860 localExitZ = sct_localEndPosition.z();
861 }
862
863 double distX = std::abs(std::abs(localExitX)-std::abs(localEntryX));
864 double distY = std::abs(std::abs(localExitY)-std::abs(localEntryY));
865
866 if(m_SmearPixel) { // Smear Pixel
867 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
868 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixel exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
869 m_x_entry_pixel = localEntryX;
870 m_y_entry_pixel = localEntryY;
871 m_z_entry_pixel = localEntryZ;
872 m_x_exit_pixel = localExitX;
873 m_y_exit_pixel = localExitY;
874 m_z_exit_pixel = localExitZ;
875 } else { // Smear SCT
876 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT start position --- " << localEntryX << ", " << localEntryY << ", " << localEntryZ );
877 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT exit position --- " << localExitX << ", " << localExitY << ", " << localExitZ );
878 m_x_entry_SCT = localEntryX;
879 m_y_entry_SCT = localEntryY;
880 m_z_entry_SCT = localEntryZ;
881 m_x_exit_SCT = localExitX;
882 m_y_exit_SCT = localExitY;
883 m_z_exit_SCT = localExitZ;
884 }
885
886 Amg::Vector2D localEntry(localEntryX,localEntryY);
887 Amg::Vector2D localExit(localExitX,localExitY);
888
889 // the pixel positions and other needed stuff for the geometrical clustering
890 std::vector<Identifier> rdoList;
891
892 Amg::Vector3D localDirection(localExitX-localEntryX, localExitY-localEntryY, localExitZ-localEntryZ);
893
894 InDetDD::SiCellId entryCellId;
895 InDetDD::SiCellId exitCellId;
896
897 // get the identifier of the entry and the exit
898 Identifier entryId = hitSiDetElement->identifierOfPosition(localEntry);
899 Identifier exitId = hitSiDetElement->identifierOfPosition(localExit);
900
901 // now get the cellIds and check whether they're valid
902 entryCellId = hitSiDetElement->cellIdFromIdentifier(entryId);
903 exitCellId = hitSiDetElement->cellIdFromIdentifier(exitId);
904
905 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryId " << entryId << " --- exitId " << exitId );
906 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryCellId " << entryCellId << " --- exitCellId " << exitCellId );
907
908 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: surface " << hitSiDetElement->surface());
909
910 // entry / exit validity
911 bool entryValid = entryCellId.isValid();
912 bool exitValid = exitCellId.isValid();
913
914 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: entryValid? " << entryValid << " --- exitValid? " << exitValid );
915
916 if (!entryValid && !exitValid) continue;
917
918 // the intersecetion id and cellId of it
919 double interX = 0.5*(localEntryX+localExitX);
920 double interY = 0.5*(localEntryY+localExitY);
921
922 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter X --- " << interX );
923 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " inter Y --- " << interY );
924 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist X --- " << distX );
925 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: " << (m_SmearPixel ? "pixel" : "SCT") << " dist Y --- " << distY );
926
927 //the particle crosses at least n pixels (in x direction you have timesX, in y direction you have timesY)
928 double timesX = (m_pitch_X) ? floor(distX/m_pitch_X) : 0;
929 double timesY = (m_pitch_Y) ? floor(distY/m_pitch_Y) : 0;
930
931 double newdistX = distX - (timesX*m_pitch_X);
932 double newdistY = distY - (timesY*m_pitch_Y);
933
934 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times X --- " << timesX );
935 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: times Y --- " << timesY );
936 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist X --- " << newdistX );
937 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: new dist Y --- " << newdistY );
938 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: thickness --- " << thickness );
939
940 //Probability
941
942 double ProbY = 2*newdistY/(m_pitch_Y+newdistY);
943 double ProbX = 2*newdistX/(m_pitch_X+newdistX);
944
945 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbX --- " << ProbX );
946 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: ProbY --- " << ProbY );
947
948 // create the errors
949 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch X --- " << m_pitch_X );
950 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pitch Y --- " << m_pitch_Y );
951
952 double sigmaX = m_pitch_X/sqrt(12.);
953 double sigmaY = m_pitch_Y/sqrt(12.);
954
955 int elementX = timesX+1;
956 int elementY = timesY+1;
957
958 if(m_SmearPixel) {
959 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbY) { // number of crossed pixel is (timesY+1)+1
960 sigmaY = (double)(timesY+2)*m_pitch_Y/sqrt(12.);
961 elementY++;
962 } else // number of crossed pixel is (timesY+1)
963 sigmaY = (double)(timesY+1)*m_pitch_Y/sqrt(12.);
964
965 if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < ProbX) { // number of crossed pixel is (timesY+1)+1
966 sigmaX = (double)(timesX+2)*m_pitch_X/sqrt(12.);
967 elementX++;
968 } else // number of crossed pixel is (timesY+1)
969 sigmaX = (double)(timesX+1)*m_pitch_X/sqrt(12.);
970 }
971
972 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma X --- " << sigmaX);
973 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool " << (m_SmearPixel ? "pixel" : "SCT") << " sigma Y --- " << sigmaY);
974
975
976 double temp_X = interX;
977 double temp_Y = interY;
978
979 Amg::Vector2D intersection(interX, interY);
980
981 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection after smearing: " << intersection);
982
983 Identifier intersectionId;
984 intersectionId = hitSiDetElement->identifierOfPosition(intersection);
985
986 rdoList.push_back(intersectionId);
987 InDetDD::SiCellId currentCellId = hitSiDetElement->cellIdFromIdentifier(intersectionId);
988
989 if (!currentCellId.isValid()) continue;
990
991 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Intersection Id = " << intersectionId << " --- currentCellId = " << currentCellId );
992
993 if(m_SmearPixel) { // Smear Pixel --> Create Pixel Cluster
994
995 double lengthX = (m_pitch_X) ? elementX*m_pitch_X : 1.;
996 double lengthY = (m_pitch_Y) ? elementY*m_pitch_Y : 1.;
997
998 if (m_pitch_X == 0. || m_pitch_Y == 0.)
999 ATH_MSG_WARNING( "--- SiSmearedDigitizationTool: pitchX and/or pitchY are 0. Cluster length is forced to be 1. mm");
1000
1001 InDet::SiWidth siWidth(Amg::Vector2D(elementX,elementY), Amg::Vector2D(lengthX, lengthY));
1002
1003 InDet::PixelCluster* pixelCluster = nullptr;
1004
1005 AmgSymMatrix(2) covariance;
1006 covariance.setIdentity();
1007 covariance(Trk::locX,Trk::locX) = sigmaX*sigmaX;
1008 covariance(Trk::locY,Trk::locY) = sigmaY*sigmaY;
1009
1010 // create the cluster
1011 pixelCluster = new InDet::PixelCluster(intersectionId,
1013 std::move(rdoList),
1014 siWidth,
1015 hitSiDetElement,
1016 Amg::MatrixX(covariance));
1017 m_pixelClusterMap->insert(std::pair<IdentifierHash, InDet::PixelCluster* >(waferID, pixelCluster));
1018
1019 if (FillTruthMap(m_pixelPrdTruth, pixelCluster, hit).isFailure()) {
1020 ATH_MSG_FATAL ( "FillTruthMap() for pixel failed!" );
1021 return StatusCode::FAILURE;
1022 }
1023
1024 if (m_checkSmear) {
1025
1026 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: pixelCluster --> " << *pixelCluster);
1027 //Take info to store in the tree
1028 m_x_pixel = temp_X;
1029 m_y_pixel = temp_Y;
1030
1031 m_x_pixel_smeared = (pixelCluster->localPosition()).x();
1032 m_y_pixel_smeared = (pixelCluster->localPosition()).y();
1033
1034 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_pixel << " Y = " << m_y_pixel);
1035 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_pixel_smeared << " Y = " << m_y_pixel_smeared);
1036
1037 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (pixelCluster->globalPosition()).x() << " Y = " << (pixelCluster->globalPosition()).y());
1038 m_x_pixel_global = (pixelCluster->globalPosition()).x();
1039 m_y_pixel_global = (pixelCluster->globalPosition()).y();
1040 m_z_pixel_global = (pixelCluster->globalPosition()).z();
1041
1042 m_Err_x_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locX);
1043 m_Err_y_pixel = Amg::error(pixelCluster->localCovariance(), Trk::locY);
1044
1045 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: Error --> X = " << m_Err_x_pixel << " Y = " << m_Err_y_pixel);
1046
1047 m_currentTree -> Fill();
1048 } // End of Pix smear check
1049
1050 } else { // Smear SCT --> Create SCT Cluster
1051
1052 // prepare the clusters
1053 InDet::SCT_Cluster * sctCluster = nullptr;
1054
1055 // Pixel Design needed -------------------------------------------------------------
1056 const InDetDD::SCT_ModuleSideDesign* design_sct;
1057
1058 design_sct = dynamic_cast<const InDetDD::SCT_ModuleSideDesign*>(&hitSiDetElement->design());
1059
1060 if (!design_sct) {
1061 ATH_MSG_INFO ( "Could not get design"<< design_sct) ;
1062 continue;
1063 }
1064
1065 // Find length of strip at centre
1066 double clusterWidth = rdoList.size()*hitSiDetElement->phiPitch(intersection);
1067 const std::pair<InDetDD::SiLocalPosition, InDetDD::SiLocalPosition> ends(design_sct->endsOfStrip(intersection));
1068 double stripLength = std::abs(ends.first.xEta()-ends.second.xEta());
1069
1070 InDet::SiWidth siWidth(Amg::Vector2D(int(rdoList.size()),1),
1071 Amg::Vector2D(clusterWidth,stripLength) );
1072
1073 const Amg::Vector2D& colRow = siWidth.colRow();
1074
1075 AmgSymMatrix(2) mat;
1076 mat.setIdentity();
1077 mat(Trk::locX,Trk::locX) = sigmaX*sigmaX;
1078 mat(Trk::locY,Trk::locY) = hitSiDetElement->length()*hitSiDetElement->length()/12.;
1079
1080 // single strip - resolution close to pitch/sqrt(12)
1081 // two-strip hits: better resolution, approx. 40% lower
1082
1083 InDetDD::DetectorShape elShape = hitSiDetElement->design().shape();
1084 if(m_emulateAtlas && elShape == InDetDD::Trapezoid)
1085 { // rotation for endcap SCT
1086
1087 if(colRow.x() == 1) {
1088 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1089 }
1090 else if(colRow.x() == 2) {
1091 mat(Trk::locX,Trk::locX) = pow(0.27*siWidth.phiR(),2)/12;
1092 }
1093 else {
1094 mat(Trk::locX,Trk::locX) = pow(siWidth.phiR(),2)/12;
1095 }
1096
1097 mat(Trk::locY,Trk::locY) = pow(siWidth.z()/colRow.y(),2)/12;
1098 double sn = hitSiDetElement->sinStereoLocal(intersection);
1099 double sn2 = sn*sn;
1100 double cs2 = 1.-sn2;
1101 double w = hitSiDetElement->phiPitch(intersection)/hitSiDetElement->phiPitch();
1102 double v0 = mat(Trk::locX, Trk::locX)*w*w;
1103 double v1 = mat(Trk::locY, Trk::locY);
1104 mat(Trk::locX, Trk::locX) = (cs2*v0+sn2*v1);
1105 mat(Trk::locY, Trk::locX) = (sn*sqrt(cs2)*(v0-v1));
1106 mat(Trk::locY, Trk::locY) = (sn2*v0+cs2*v1);
1107 } // End of rotation endcap SCT
1108
1109
1110 sctCluster = new InDet::SCT_Cluster(intersectionId,
1112 std::move(rdoList),
1113 siWidth,
1114 hitSiDetElement,
1115 Amg::MatrixX(mat));
1116
1117 m_sctClusterMap->insert(std::pair<IdentifierHash, InDet::SCT_Cluster* >(waferID, sctCluster));
1118
1119 if (FillTruthMap(m_SCTPrdTruth, sctCluster, hit).isFailure()) {
1120 ATH_MSG_FATAL ( "FillTruthMap() for SCT failed!" );
1121 return StatusCode::FAILURE;
1122 }
1123
1124 if (m_checkSmear) {
1125
1126 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: SCT_Cluster --> " << *sctCluster);
1127
1128 //Take info to store in the tree
1129 m_x_SCT = m_useDiscSurface ? temp_Y : temp_X;
1130 m_x_SCT_smeared = (sctCluster->localPosition()).x();
1131
1132 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: BEFORE SMEARING LocalPosition --> X = " << m_x_SCT );
1133 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: LocalPosition --> X = " << m_x_SCT_smeared );
1134
1135 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: GlobalPosition --> X = " << (sctCluster->globalPosition()).x() << " Y = " << (sctCluster->globalPosition()).y());
1136 m_x_SCT_global = (sctCluster->globalPosition()).x();
1137 m_y_SCT_global = (sctCluster->globalPosition()).y();
1138 m_z_SCT_global = (sctCluster->globalPosition()).z();
1139
1140 m_currentTree -> Fill();
1141 } // End smear checking
1142 } // End SCT
1143 } // while
1144 } //while
1145 return StatusCode::SUCCESS;
1146}
1147
1148
1149StatusCode SiSmearedDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
1150{
1151 // Get PixelDetectorElementCollection
1152 const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
1153 if (m_SmearPixel) {
1155 elementsPixel = pixelDetEle.retrieve();
1156 if (elementsPixel==nullptr) {
1157 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
1158 return StatusCode::FAILURE;
1159 }
1160 }
1161 // Get SCT_DetectorElementCollection
1162 const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
1163 if (not m_SmearPixel) {
1165 elementsSCT = sctDetEle.retrieve();
1166 if (elementsSCT==nullptr) {
1167 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
1168 return StatusCode::FAILURE;
1169 }
1170 }
1171
1172 if ( m_SmearPixel ) { // Store Pixel RIOs
1173
1174 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel createAndStoreRIOs() ---" );
1175
1176 Pixel_detElement_RIO_map::iterator i = m_pixelClusterMap->begin();
1177 Pixel_detElement_RIO_map::iterator e = m_pixelClusterMap->end();
1178
1179 for ( ; i != e; i = m_pixelClusterMap->upper_bound(i->first) ) {
1180
1181 std::pair <Pixel_detElement_RIO_map::iterator, Pixel_detElement_RIO_map::iterator> range;
1182 range = m_pixelClusterMap->equal_range(i->first);
1183
1184 Pixel_detElement_RIO_map::iterator firstDetElem;
1185 firstDetElem = range.first;
1186
1187 IdentifierHash waferID;
1188 waferID = firstDetElem->first;
1189
1190 const InDetDD::SiDetectorElement* detElement = elementsPixel->getDetectorElement(waferID);
1191
1192 InDet::PixelClusterCollection *clusterCollection = new InDet::PixelClusterCollection(waferID);
1193 clusterCollection->setIdentifier(detElement->identify());
1194
1195 for ( Pixel_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1196
1197 InDet::PixelCluster* pixelCluster = (*iter).second;
1198 pixelCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1199 clusterCollection->push_back(pixelCluster);
1200 }
1201
1202 if ( m_pixelClusterContainer->addCollection( clusterCollection, waferID ).isFailure() ) {
1203 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1204 }
1205 } // end for
1206
1207 m_pixelClusterMap->clear();
1208
1209 }
1210 else { // Store SCT RIOs
1211
1212 ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SCT createAndStoreRIOs() ---" );
1213
1214 SCT_detElement_RIO_map::iterator i = m_sctClusterMap->begin();
1215 SCT_detElement_RIO_map::iterator e = m_sctClusterMap->end();
1216
1217 for ( ; i != e; i = m_sctClusterMap->upper_bound(i->first) ) {
1218 std::pair <SCT_detElement_RIO_map::iterator, SCT_detElement_RIO_map::iterator> range;
1219 range = m_sctClusterMap->equal_range(i->first);
1220
1221 SCT_detElement_RIO_map::iterator firstDetElem;
1222 firstDetElem = range.first;
1223
1224 IdentifierHash waferID;
1225 waferID = firstDetElem->first;
1226 const InDetDD::SiDetectorElement* detElement = elementsSCT->getDetectorElement(waferID);
1227
1228 InDet::SCT_ClusterCollection *clusterCollection = new InDet::SCT_ClusterCollection(waferID);
1229 clusterCollection->setIdentifier(detElement->identify());
1230
1231
1232 for ( SCT_detElement_RIO_map::iterator iter = range.first; iter != range.second; ++iter ) {
1233 InDet::SCT_Cluster* sctCluster = (*iter).second;
1234 sctCluster->setHashAndIndex(clusterCollection->identifyHash(),clusterCollection->size());
1235 clusterCollection->push_back(sctCluster);
1236 }
1237
1238 if ( m_sctClusterContainer->addCollection( clusterCollection, clusterCollection->identifyHash() ).isFailure() ) {
1239 ATH_MSG_WARNING( "Could not add collection to Identifyable container !" );
1240 }
1241
1242 } // end for
1243
1244 m_sctClusterMap->clear();
1245 }
1246
1247 return StatusCode::SUCCESS;
1248}
#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
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