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