ATLAS Offline Software
Loading...
Searching...
No Matches
VP1SimHitSystem.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*
6 * Major updates:
7 * - 2022 Jan, Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
8 * Added visualization for Calorimeters' sim hits
9 *
10 */
12#include "ui_simhitcontrollerform.h"
13
16
18
25
26// Section of includes for global calo hits
27#include "CaloDetDescr/CaloDetDescrElement.h"
30
31// Section of includes for LAr calo hits
32#include "LArSimEvent/LArHit.h"
34
35// Section of includes for Tile calo hits
40
46
48
50
51#include <Inventor/C/errors/debugerror.h>
52#include <Inventor/nodes/SoDrawStyle.h>
53#include <Inventor/nodes/SoMaterial.h>
54#include <Inventor/nodes/SoSeparator.h>
55#include <Inventor/nodes/SoSwitch.h>
56#include <Inventor/nodes/SoVertexProperty.h>
57#include <Inventor/nodes/SoPointSet.h>
58#include <Inventor/SbColor.h>
59
60#include <QMap>
61#include <QSet>
62
64{
65public:
66 QMap<QString,SoSwitch*> switchMap;
67 QMap<QString,SbColor> colorMap;
68 QMap<QCheckBox*,QString> checkBoxNamesMap;
69 QMap<QString,QCheckBox*> checkBoxMap;
70 QSet<QString> hitsThisEvent;
71 StoreGateSvc * sg = nullptr;
72
73 // Managers
76 std::unique_ptr<CaloDetDescrManager> lar_dd_man;
77
78 // ID helpers
79 const TileID* tile_id{nullptr};
80
81};
82
84 :IVP13DSystemSimple("Sim Hits","Display simulation hits from trackers and calorimeters","Vakho Tsulaia <Vakhtang.Tsulaia@cern.ch>, Riccardo Maria Bianchi <Riccardo.Maria.Bianchi@cern.ch>"),
86{
87}
88
94
96{
97 QWidget* controller = new QWidget(0);
98 Ui::SimHitControllerForm ui;
99 ui.setupUi(controller);
100
101 // Populate Check Box Names Map
102 m_clockwork->checkBoxNamesMap.insert(ui.chbxPixelHits,"Pixel");
103 m_clockwork->checkBoxNamesMap.insert(ui.chbxSCTHits,"SCT");
104 m_clockwork->checkBoxNamesMap.insert(ui.chbxTRTHits,"TRT");
105 m_clockwork->checkBoxNamesMap.insert(ui.chbxMDTHits,"MDT");
106 m_clockwork->checkBoxNamesMap.insert(ui.chbxRPCHits,"RPC");
107 m_clockwork->checkBoxNamesMap.insert(ui.chbxTGCHits,"TGC");
108 m_clockwork->checkBoxNamesMap.insert(ui.chbxCSCHits,"CSC");
109 m_clockwork->checkBoxNamesMap.insert(ui.chbxMMHits,"MM");
110 m_clockwork->checkBoxNamesMap.insert(ui.chbxsTGCHits,"sTGC");
111 m_clockwork->checkBoxNamesMap.insert(ui.chbxLArEMBHits,"LArEMB");
112 m_clockwork->checkBoxNamesMap.insert(ui.chbxLArEMECHits,"LArEMEC");
113 m_clockwork->checkBoxNamesMap.insert(ui.chbxLArFCALHits,"LArFCAL");
114 m_clockwork->checkBoxNamesMap.insert(ui.chbxLArHECHits,"LArHEC");
115 m_clockwork->checkBoxNamesMap.insert(ui.chbxTileHits,"Tile");
116 m_clockwork->checkBoxNamesMap.insert(ui.chbxGenericMuonHits,"Generic Muon");
117 m_clockwork->checkBoxNamesMap.insert(ui.chbxForwardRegionHits,"Forward Region");
118
119 // Populate Check Box Map and connect slots
120 for(QCheckBox* cb : m_clockwork->checkBoxNamesMap.keys())
121 {
122 connect(cb,SIGNAL(toggled(bool)),this,SLOT(checkboxChanged()));
123 m_clockwork->checkBoxMap.insert(m_clockwork->checkBoxNamesMap[cb],cb);
124 }
125
126 return controller;
127}
128
130{
131 // Populate Color Map
132 m_clockwork->colorMap.insert("Pixel",SbColor(0,0,1));
133 m_clockwork->colorMap.insert("SCT",SbColor(1,1,1)); // white
134 m_clockwork->colorMap.insert("TRT",SbColor(1,0,0)); // red
135 m_clockwork->colorMap.insert("MDT",SbColor(.98,.8,.21));
136 m_clockwork->colorMap.insert("RPC",SbColor(0,.44,.28));
137 m_clockwork->colorMap.insert("TGC",SbColor(0,.631244,.748016));
138 m_clockwork->colorMap.insert("CSC",SbColor(.21,.64,1.));
139 m_clockwork->colorMap.insert("MM",SbColor(VP1ColorUtils::getSbColorFromRGB(28, 162, 230))); // Carolina Blue
140 m_clockwork->colorMap.insert("sTGC",SbColor(VP1ColorUtils::getSbColorFromRGB(255, 255, 255))); // White
141 m_clockwork->colorMap.insert("LArEMB",SbColor(VP1ColorUtils::getSbColorFromRGB(247, 187, 109))); // Mellow Apricot
142 m_clockwork->colorMap.insert("LArEMEC",SbColor(VP1ColorUtils::getSbColorFromRGB(230, 151, 48))); // Carrot Orange
143 m_clockwork->colorMap.insert("LArFCAL",SbColor(VP1ColorUtils::getSbColorFromRGB(212, 134, 32))); // Fulvous
144 m_clockwork->colorMap.insert("LArHEC",SbColor(VP1ColorUtils::getSbColorFromRGB(184, 114, 24))); // Copper
145 //m_clockwork->colorMap.insert("Tile",SbColor(VP1ColorUtils::getSbColorFromRGB(28, 162, 230))); // Carolina Blue --> Note: this is nice, but it disappears when superimposed to the azure Tile geometry default material
146 m_clockwork->colorMap.insert("Tile",SbColor(VP1ColorUtils::getSbColorFromRGB(164, 78, 207))); // Purple Plum
147 m_clockwork->colorMap.insert("Generic Muon",SbColor(.21,.64,1.));
148 m_clockwork->colorMap.insert("Forward Region",SbColor(.21,.64,1.));
149
150
151 // ------------- DD Managers and ID Helpers -------------
152 StatusCode status = detstore->retrieve(m_clockwork->tile_dd_man);
153 if(status.isFailure() || m_clockwork->tile_dd_man==nullptr) {
154 //m_clockwork->noCalo = true;
155 messageDebug("Unable to retrieve Tile DD Manager");
156 return;
157 }
158 m_clockwork->tile_id = m_clockwork->tile_dd_man->get_id();
159 if(m_clockwork->tile_id==nullptr) {
160 //m_clockwork->noCalo = true;
161 messageDebug("0 pointer to Tile ID Helper");
162 return;
163 }
164 status = detstore->retrieve(m_clockwork->trt_dd_man,"TRT");
165 if(status.isFailure() || m_clockwork->trt_dd_man==nullptr) {
166 messageDebug("Unable to retrieve TRT DD Manager");
167 return;
168 }
170}
171
173{
174 // --- Draw style: POINTS
175 SoDrawStyle* ds = new SoDrawStyle();
176 ds->style.setValue(SoDrawStyle::POINTS);
177 ds->pointSize=4;
178 root->addChild(ds);
179
180 // Keep SG pointer
181 m_clockwork->sg = sg;
182
183 // clean up
184 m_clockwork->switchMap.clear();
185 m_clockwork->hitsThisEvent.clear();
186
187 if(!sg)
188 {
189 message("0 pointer to the Store Gate!");
190 return;
191 }
192
193 for(const QString& detector : m_clockwork->checkBoxMap.keys())
194 {
195 // Add switch, off by default
196 SoSwitch* sw = new SoSwitch();
197 sw->whichChild = SO_SWITCH_NONE;
198 root->addChild(sw);
199 m_clockwork->switchMap.insert(detector,sw);
200
201 // Build subtree if the check box is ON
202 if(m_clockwork->checkBoxMap.contains(detector) &&
203 m_clockwork->checkBoxMap[detector]->isChecked())
204 {
205 buildHitTree(detector);
206 sw->whichChild = SO_SWITCH_ALL;
207 }
208 updateGUI();
209 }
210}
211
213{
214 // Get ChB pointer
215 QCheckBox* cb = dynamic_cast<QCheckBox*>(sender());
216 if(cb && m_clockwork->checkBoxNamesMap.contains(cb))
217 {
218 // Get detector name
219 QString detector = m_clockwork->checkBoxNamesMap[cb];
220 if(m_clockwork->switchMap.contains(detector))
221 {
222 // Get swtich
223 SoSwitch* sw = m_clockwork->switchMap[detector];
224 if(cb->isChecked()){
225 // Build subtree if necessary
226 if(!m_clockwork->hitsThisEvent.contains(detector))
227 buildHitTree(detector);
228 sw->whichChild = SO_SWITCH_ALL;
229 }
230 else
231 sw->whichChild = SO_SWITCH_NONE;
232 } else {
233 message("WARNING: Unknown detector:"+detector);
234 }
235 }
236}
237
238
239void VP1SimHitSystem::buildHitTree(const QString& detector)
240{
241 messageVerbose("buildHitTree for "+detector);
242 if(m_clockwork->hitsThisEvent.contains(detector)) {
243 messageVerbose(" in hitsThisEvent"); return;
244 }
245 if(!m_clockwork->colorMap.contains(detector)) {
246 messageVerbose("not in colorMap"); return;
247 }
248 if(!m_clockwork->switchMap.contains(detector)) {
249 messageVerbose("not in switchMap"); return;
250 }
251
252 // -- Initializations
253 StoreGateSvc* sg = m_clockwork->sg;
254 SoSwitch* sw = m_clockwork->switchMap[detector];
255 unsigned int hitCount = 0;
256
257 SoVertexProperty* hitVtxProperty = new SoVertexProperty();
258 SoPointSet* hitPointSet = new SoPointSet();
259
260 hitVtxProperty->enableNotify(FALSE);
261 hitPointSet->enableNotify(FALSE);
262
263 // -- COLOR
264 SoMaterial* material = new SoMaterial();
265 material->diffuseColor.setValue(m_clockwork->colorMap[detector]);
266
267 sw->addChild(material);
268
269 // Take hits from SG
270 if(detector=="Pixel")
271 {
272 //
273 // Pixel:
274 //
275 const SiHitCollection* p_collection = nullptr;
276 if(sg->retrieve(p_collection,"PixelHits")==StatusCode::SUCCESS)
277 {
278 for (const SiHit& hit : *p_collection)
279 {
280 GeoSiHit ghit(hit);
281 if(!ghit) continue;
282 HepGeom::Point3D<double> u = ghit.getGlobalPosition();
283 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
284 }
285 }
286 else
287 message("Unable to retrieve Pixel Hits");
288 }
289 else if(detector=="SCT")
290 {
291 //
292 // SCT:
293 //
294 const SiHitCollection* s_collection = 0;
295 if(sg->retrieve(s_collection,"SCT_Hits")==StatusCode::SUCCESS)
296 {
297 for (const SiHit& hit : *s_collection)
298 {
299 GeoSiHit ghit(hit);
300 if (!ghit) continue;
301 HepGeom::Point3D<double> u = ghit.getGlobalPosition();
302 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
303 }
304 }
305 else
306 message("Unable to retrieve SCT Hits");
307 }
308 else if(detector=="TRT")
309 {
310 //
311 // TRT:
312 //
313 const TRTUncompressedHitCollection* t_collection = nullptr;
314 if(sg->retrieve(t_collection,"TRTUncompressedHits")==StatusCode::SUCCESS)
315 {
316 for (const TRTUncompressedHit& hit : *t_collection)
317 {
318 GeoTRTUncompressedHit ghit(hit);
319 if(!ghit) continue;
321 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(), u.z() );
322 }
323 }
324 else
325 message("Unable to retrieve TRT Hits");
326 }
327 else if(detector=="LArEMB" || detector=="LArEMEC" || detector=="LArFCAL" || detector=="LArHEC" )
328 {
329 //
330 // LAr:
331 //
332 // NOTE: to access additional LAr simHit data, see:
333 // Simulation/Tools/HitAnalysis/src/CaloHitAnalysis.cxx
334 //
335 const LArHitContainer* lar_collection;
336
337 std::string collName{"LArHit"};
338 std::string suff{""};
339
340 if (detector=="LArEMB")
341 suff = "EMB";
342 else if (detector=="LArEMEC")
343 suff = "EMEC";
344 else if (detector=="LArFCAL")
345 suff = "FCAL";
346 else if (detector=="LArHEC")
347 suff = "HEC";
348 collName += suff; // e.g., we get 'LArHitEMB'
349
350 if(sg->retrieve(lar_collection, collName)==StatusCode::SUCCESS)
351 {
352 for (auto hi : *lar_collection ) {
353
354 const LArHit* larHit = hi;
355 const CaloDetDescrElement* ddElement = m_clockwork->lar_dd_man->get_element(larHit->cellID());
356 if (ddElement)
357 handleDetDescrElementHit(ddElement, hitVtxProperty, hitCount);
358 else
359 message("Unable to retrieve the CaloDetDescrElement!");
360 }
361 }
362 else
363 message("Unable to retrieve " + QString::fromStdString(collName) );
364 }
365 else if(detector=="Tile")
366 {
367 //
368 // Tile:
369 //
370 // For more Tile simHits data, see:
371 // Simulation/Tools/HitAnalysis/src/CaloHitAnalysis.cxx
372 //
373 const TileHitVector* t_collection = nullptr;
374
375 if(sg->retrieve(t_collection,"TileHitVec")==StatusCode::SUCCESS)
376 {
377 for (const TileHit& hit : *t_collection) {
378 Identifier pmt_id = hit.identify();
379 Identifier cell_id = m_clockwork->tile_id->cell_id(pmt_id);
380 const CaloDetDescrElement* ddElement = (m_clockwork->tile_id->is_tile_aux(cell_id)) ? 0 : m_clockwork->tile_dd_man->get_cell_element(cell_id);
381 if (ddElement)
382 handleDetDescrElementHit(ddElement, hitVtxProperty, hitCount);
383 else
384 message("Unable to retrieve the CaloDetDescrElement!");
385 }
386 }
387 else
388 message("Unable to retrieve Tile Hits");
389 }
390 else if(detector=="MDT")
391 {
392 //
393 // MDT:
394 //
395 const MDTSimHitCollection* mdt_collection = nullptr;
396 if(sg->retrieve(mdt_collection)==StatusCode::SUCCESS)
397 {
398 for (const MDTSimHit& hit : *mdt_collection)
399 {
400 GeoMDTHit ghit(hit);
401 if(!ghit) continue;
403 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
404 }
405 }
406 else
407 message("Unable to retrieve MDT Hits");
408 }
409 else if(detector=="RPC")
410 {
411 //
412 // RPC:
413 //
414 const RPCSimHitCollection* rpc_collection = nullptr;
415 if(sg->retrieve(rpc_collection)==StatusCode::SUCCESS) {
416 for (const RPCSimHit& hit : *rpc_collection)
417 {
418 GeoRPCHit ghit(hit);
419 if(!ghit) continue;
421 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
422 }
423 }
424 else
425 message("Unable to retrieve RPC Hits");
426 }
427 else if(detector=="TGC")
428 {
429 //
430 // TGC:
431 //
432 const TGCSimHitCollection* tgc_collection = nullptr;
433 if (sg->retrieve(tgc_collection)==StatusCode::SUCCESS)
434 {
435 for (const TGCSimHit& hit : *tgc_collection)
436 {
437 GeoTGCHit ghit(hit);
438 if(!ghit) continue;
440 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
441 }
442 }
443 else
444 message("Unable to retrieve TGC Hits");
445 }
446 else if(detector=="CSC")
447 {
448 //
449 // CSC:
450 //
451 const CSCSimHitCollection* csc_collection = nullptr;
452 if(sg->retrieve(csc_collection)==StatusCode::SUCCESS)
453 {
454 for (const CSCSimHit& hit : *csc_collection)
455 {
456 GeoCSCHit ghit(hit);
457 if (!ghit) continue;
459 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
460 }
461 }
462 else
463 message("Unable to retrieve CSC Hits");
464 }
465 else if(detector=="MM")
466 {
467 //
468 // NSW / MM:
469 //
470 const MMSimHitCollection* mm_collection;
471 if(sg->retrieve(mm_collection)==StatusCode::SUCCESS)
472 {
473 for( const MMSimHit& hit : *mm_collection )
474 {
475 GeoMMHit ghit(hit);
476 if(!ghit) continue;
478 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
479 }
480 }
481 else
482 message("Unable to retrieve MM Hits");
483 }
484 else if(detector=="sTGC")
485 {
486 //
487 // NSW / sTGC:
488 //
489 const sTGCSimHitCollection* stgc_collection;
490 if(sg->retrieve(stgc_collection)==StatusCode::SUCCESS)
491 {
492 for( const sTGCSimHit& hit : *stgc_collection )
493 {
494 GeosTGCHit ghit(hit);
495 if(!ghit) continue;
497 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
498 }
499 }
500 else
501 message("Unable to retrieve sTGC Hits");
502 }
503 else if(detector=="Generic Muon")
504 {
505 //
506 // Generic:
507 //
508 message("Trying for Generic Muon (as many collections as can be found)");
509 for(const QString& key : VP1SGContentsHelper(this).getKeys<GenericMuonSimHitCollection>()) {
510 const GenericMuonSimHitCollection* generic_collection = nullptr;
511 if(sg->retrieve( generic_collection,key.toStdString().c_str() )==StatusCode::SUCCESS)
512 {
513 messageVerbose("Retrieved"+key+"with size: "+str(generic_collection->size()));
514 std::cout<<"Got collection with size: "<<generic_collection->size()<<std::endl;
515
516 //unsigned int i=0; // for DEBUG only
517 for (const GenericMuonSimHit& hit : *generic_collection)
518 {
519 // std::cout << "Got hit number: " << i++ << std::endl; // for DEBUG only
520 const GenericMuonSimHit ghit(hit);
521 const Amg::Vector3D& u = ghit.globalPosition();
522 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
523 }
524 }
525 else
526 message("Unable to retrieve Generic Muon Hits from "+key);
527 }
528 } else if(detector=="Forward Region")
529 {
530 //
531 // Generic:
532 //
533 message("Trying for ForwardRegion (as many collections as can be found)");
534 for(const QString& key : VP1SGContentsHelper(this).getKeys<SimulationHitCollection>()) {
535 const SimulationHitCollection* generic_collection = nullptr;
536 if(sg->retrieve( generic_collection,key.toStdString().c_str() )==StatusCode::SUCCESS)
537 {
538 messageVerbose("Retrieved"+key+"with size: "+str(generic_collection->size()));
539 std::cout<<"Got collection with size: "<<generic_collection->size()<<std::endl;
540
541 //unsigned int i=0; // for DEBUG only
542 for (const SimulationHit& hit : *generic_collection)
543 {
544 // std::cout << "Got hit number: " << i++ << std::endl; // for DEBUG only
545 const SimulationHit ghit(hit);
547 hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z());
548 }
549 }
550 else
551 message("Unable to retrieve Simulation Hits from "+key);
552 }
553 }
554
555 // Add to the switch
556 hitPointSet->numPoints=hitCount;
557 hitPointSet->vertexProperty.setValue(hitVtxProperty);
558 sw->addChild(hitPointSet);
559 hitPointSet->enableNotify(TRUE);
560 hitVtxProperty->enableNotify(TRUE);
561}
562
563
564void VP1SimHitSystem::handleDetDescrElementHit(const CaloDetDescrElement *hitElement, SoVertexProperty* hitVtxProperty, unsigned int &hitCount)
565{
566 float x = hitElement->x();
567 float y = hitElement->y();
568 double z = hitElement->z();
569 hitVtxProperty->vertex.set1Value(hitCount++,x,y,z);
570}
571
AtlasHitsVector< CSCSimHit > CSCSimHitCollection
std::unique_ptr< CaloDetDescrManager > buildCaloDetDescrNoAlign(ISvcLocator *svcLocator, IMessageSvc *msgSvc)
Definition of CaloDetDescrManager.
AtlasHitsVector< GenericMuonSimHit > GenericMuonSimHitCollection
AtlasHitsVector< MDTSimHit > MDTSimHitCollection
AtlasHitsVector< MMSimHit > MMSimHitCollection
AtlasHitsVector< RPCSimHit > RPCSimHitCollection
AtlasHitsVector< SiHit > SiHitCollection
AtlasHitsVector< SimulationHit > SimulationHitCollection
AtlasHitsVector< TGCSimHit > TGCSimHitCollection
AtlasHitsVector< TRTUncompressedHit > TRTUncompressedHitCollection
AtlasHitsVector< TileHit > TileHitVector
#define y
#define x
#define z
size_type size() const
This class groups all DetDescr information related to a CaloCell.
const Amg::Vector3D & globalPosition() const
Amg::Vector3D getGlobalPosition() const
Amg::Vector3D getGlobalPosition() const
Amg::Vector3D getGlobalPosition() const
Amg::Vector3D getGlobalPosition() const
HepGeom::Point3D< double > getGlobalPosition() const
Amg::Vector3D getGlobalPosition() const
This adaptor class allows TRT_UncompressedHits to behave as if they knew which detector they were in.
HepGeom::Point3D< double > getGlobalPosition(const InDetDD::TRT_DetectorManager *mgr) const
Amg::Vector3D getGlobalPosition() const
IVP13DSystemSimple(const QString &name, const QString &information, const QString &contact_info)
void messageVerbose(const QString &) const
void messageDebug(const QString &) const
void message(const QString &) const
ISvcLocator * serviceLocator() const
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Hit collection.
Class to store hit energy and time in LAr cell from G4 simulation.
Definition LArHit.h:25
Identifier cellID() const
Definition LArHit.h:108
Definition SiHit.h:19
CLHEP::Hep3Vector position
const StepPoint & pre() const
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
Helper class for TileCal offline identifiers.
Definition TileID.h:67
static SbColor getSbColorFromRGB(const unsigned int r, const unsigned int g, const unsigned int b)
QMap< QString, SoSwitch * > switchMap
QMap< QString, QCheckBox * > checkBoxMap
std::unique_ptr< CaloDetDescrManager > lar_dd_man
const TileDetDescrManager * tile_dd_man
QMap< QString, SbColor > colorMap
QMap< QCheckBox *, QString > checkBoxNamesMap
const InDetDD::TRT_DetectorManager * trt_dd_man
Clockwork * m_clockwork
void buildHitTree(const QString &detector)
void handleDetDescrElementHit(const CaloDetDescrElement *hitElement, SoVertexProperty *hitVtxProperty, unsigned int &hitCount)
void buildEventSceneGraph(StoreGateSvc *sg, SoSeparator *root)
QWidget * buildController()
void systemcreate(StoreGateSvc *detstore)
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
Eigen::Matrix< double, 3, 1 > Vector3D
IMessageSvc * getMessageSvc(bool quiet=false)
AtlasHitsVector< sTGCSimHit > sTGCSimHitCollection