ATLAS Offline Software
Loading...
Searching...
No Matches
VP1MbtsHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
8
10
11#include <Inventor/nodes/SoNode.h>
12#include <Inventor/nodes/SoSeparator.h>
13
15
17#include "GeoModelKernel/GeoFullPhysVol.h"
18#include "GeoModelKernel/GeoVolumeCursor.h"
19#include "GeoModelKernel/GeoTrd.h"
20
23
24#include <stdexcept>
25
27{
28 public:
29 // ID helper
30 const TileTBID* tiletb_id = nullptr;
31
32 // Event data
34
35 // VP1Mbts objects of this event
36 std::vector<VP1Mbts*> vp1_mbts;
37
38 // Maps
41
42 // Separator helper
43 SoSeparator* separator = nullptr;
44
46};
47
48
51 m_outline(outline),
52 m_clipRadius(10e8),
53 m_run2Geo(false)
54{
55 m_clockwork->tiletb_id = 0;
56 m_clockwork->mbts_container = 0;
57 m_clockwork->separator = 0;
58}
59
60
66
68{
69 // Initialize identifier helper
70 StatusCode status = detstore->retrieve(m_clockwork->tiletb_id);
71 if(status.isFailure() || m_clockwork->tiletb_id==0)
72 throw std::runtime_error("Unable to retrieve TileTBID");
73
74
75 VP1CC_MbtsXfMap aTransforms1, aTransforms2, cTransforms1, cTransforms2;
76
77 // Get Stored Full phys volumes for LAr end caps
78 StoredPhysVol* storedLArECA = 0;
79 StoredPhysVol* storedLArECC = 0;
80
81 status = detstore->retrieve(storedLArECA,"LARCRYO_EC_POS");
82 if(status.isFailure() || storedLArECA == 0)
83 throw std::runtime_error("Failed to locate LAr Endcap A");
84
85 status = detstore->retrieve(storedLArECC,"LARCRYO_EC_NEG");
86 if(status.isFailure() || storedLArECC == 0)
87 throw std::runtime_error("Failed to locate LAr Endcap C");
88
89
90 // Get full physical volumes and their absolute transforms
91 GeoFullPhysVol* pvLArECA = storedLArECA->getPhysVol();
92 GeoFullPhysVol* pvLArECC = storedLArECC->getPhysVol();
93
94 GeoTrf::Transform3D xfLArECA = pvLArECA->getAbsoluteTransform();
95 GeoTrf::Transform3D xfLArECC = pvLArECC->getAbsoluteTransform();
96
97 // Find a pointer to MBTS mother volume and its local transform
98 GeoTrf::Transform3D xfMbtsMother;
99 PVConstLink pvMbtsMother;
100 bool mbtsExists = false;
101
102 GeoVolumeCursor cursor1(pvLArECA);
103 while(!cursor1.atEnd())
104 {
105 PVConstLink child = cursor1.getVolume();
106 if(child->getLogVol()->getName() == "MBTS_mother")
107 {
108 pvMbtsMother = child;
109 xfMbtsMother = cursor1.getTransform();
110 mbtsExists = true;
111 break;
112 }
113 cursor1.next();
114 }
115
116 if(!mbtsExists)
117 throw std::runtime_error("Unable to find MBTS volume");
118
119 // Find shapes of scintillators and their local transforms
120 // Here we need to distinguish between two geometry description: "OLD" and "NEW"
121 //
122 // OLD description: scintillator volumes are placed directly into the mother.
123 // each scintillator colume has copy number assigned to it
124 //
125 // NEW description: here is the volume hierarchy tree leading from MBTS_mother to scintillators:
126 //
127 // MBTS_mother
128 // MBTSAirEnv <--- Copy numbers
129 // MBTSAluEnv
130 // MBTSAirInAlu
131 // MBTS1
132 // MBTS1
133
134 GeoVolumeCursor cursor2(pvMbtsMother);
135
136 PVConstLink pvScin1;
137 PVConstLink pvScin2;
138
139 bool scin1Exists = false;
140 bool scin2Exists = false;
141
142 while(!cursor2.atEnd())
143 {
144 PVConstLink child = cursor2.getVolume();
145 std::string childName = child->getLogVol()->getName();
146 if(childName.find("MBTSAirEnv")!=std::string::npos) {
147 m_run2Geo = true;
148 break;
149 }
150 if(childName == "MBTS1")
151 {
152 scin1Exists = true;
153 pvScin1 = child;
154 int copyNo= cursor2.getId().value();
155
156 aTransforms1[copyNo] = xfLArECA * xfMbtsMother * cursor2.getTransform();
157 cTransforms1[copyNo] = xfLArECC * xfMbtsMother * cursor2.getTransform();
158 }
159 else if(childName == "MBTS2")
160 {
161 scin2Exists = true;
162 pvScin2 = child;
163 int copyNo= cursor2.getId().value();
164
165 aTransforms2[copyNo] = xfLArECA * xfMbtsMother * cursor2.getTransform();
166 cTransforms2[copyNo] = xfLArECC * xfMbtsMother * cursor2.getTransform();
167 }
168 cursor2.next();
169 }
170
171 if(m_run2Geo) {
172 GeoVolumeCursor cursor2a(pvMbtsMother);
173 while(!cursor2a.atEnd()) {
174 PVConstLink pvAirEnv = cursor2a.getVolume();
175 if(pvAirEnv->getLogVol()->getName().find("MBTSAirEnv")!=std::string::npos) {
176 int copyNo = cursor2a.getId().value();
177
178 // **** Find Aluminun Envelope ****
179 GeoVolumeCursor cursor3(pvAirEnv);
180 bool aluEnvExists(false);
181 while(!cursor3.atEnd()) {
182 if(cursor3.getVolume()->getLogVol()->getName().find("MBTSAluEnv")!=std::string::npos) {
183 aluEnvExists = true;
184 break;
185 }
186 cursor3.next();
187 }
188 if(!aluEnvExists)
189 throw std::runtime_error("Problems with MBTS geometry: Cannot find MBTSAluEnv!");
190
191 PVConstLink pvAluEnv = cursor3.getVolume();
192
193 // **** Find "Air in Aluminum" ****
194 GeoVolumeCursor cursor4(pvAluEnv);
195 bool airInAluExists(false);
196 while(!cursor4.atEnd()) {
197 if(cursor4.getVolume()->getLogVol()->getName().find("MBTSAirInAlu")!=std::string::npos) {
198 airInAluExists = true;
199 break;
200 }
201 cursor4.next();
202 }
203 if(!airInAluExists)
204 throw std::runtime_error("Problems with MBTS geometry: Cannot find MBTSAirInAlu!");
205
206 PVConstLink pvAirInAluEnv = cursor4.getVolume();
207
208 // **** Find scintillators ****
209 GeoVolumeCursor cursor5(pvAirInAluEnv);
210 while(!cursor5.atEnd()) {
211 PVConstLink child = cursor5.getVolume();
212 if(child->getLogVol()->getName()=="MBTS1") {
213 scin1Exists = true;
214 pvScin1 = child;
215 aTransforms1[copyNo] = xfLArECA * xfMbtsMother * cursor2a.getTransform() * cursor3.getTransform() * cursor4.getTransform() * cursor5.getTransform();
216 cTransforms1[copyNo] = xfLArECC * xfMbtsMother * cursor2a.getTransform() * cursor3.getTransform() * cursor4.getTransform() * cursor5.getTransform();
217 }
218 if(child->getLogVol()->getName()=="MBTS2") {
219 scin2Exists = true;
220 pvScin2 = child;
221 aTransforms2[copyNo] = xfLArECA * xfMbtsMother * cursor2a.getTransform() * cursor3.getTransform() * cursor4.getTransform() * cursor5.getTransform();
222 cTransforms2[copyNo] = xfLArECC * xfMbtsMother * cursor2a.getTransform() * cursor3.getTransform() * cursor4.getTransform() * cursor5.getTransform();
223 }
224 cursor5.next();
225 }
226 } // Dealing with MBTSAirEnv
227 cursor2a.next();
228 } // Looping over MBTS mother daughters
229 } // In New Geometry
230
231 if(!scin1Exists)
232 throw std::runtime_error("No MBTS1 in the geometry");
233
234 if(!scin2Exists)
235 throw std::runtime_error("No MBTS2 in the geometry");
236
237 const GeoShape* shape1 = pvScin1->getLogVol()->getShape();
238 const GeoShape* shape2 = pvScin2->getLogVol()->getShape();
239
240 const GeoTrd* trd1 = dynamic_cast<const GeoTrd*>(shape1);
241 const GeoTrd* trd2 = dynamic_cast<const GeoTrd*>(shape2);
242
243 if(trd1==0)
244 throw std::runtime_error("The shape of MBTS1 is not TRD");
245
246 if(trd2==0)
247 throw std::runtime_error("The shape of MBTS2 is not TRD");
248
249 // Create new Scin Info objects and store them into map
250 VP1CC_MbtsScinInfo* scinInfo1 = new VP1CC_MbtsScinInfo();
251 VP1CC_MbtsScinInfo* scinInfo2 = new VP1CC_MbtsScinInfo();
252
253 scinInfo1->dx1 = trd1->getXHalfLength1();
254 scinInfo1->dx2 = trd1->getXHalfLength2();
255 scinInfo1->dy1 = trd1->getYHalfLength1();
256 scinInfo1->dy2 = trd1->getYHalfLength2();
257 scinInfo1->dz = trd1->getZHalfLength();
258 scinInfo1->aTransforms = aTransforms1;
259 scinInfo1->cTransforms = cTransforms1;
260
261 scinInfo2->dx1 = trd2->getXHalfLength1();
262 scinInfo2->dx2 = trd2->getXHalfLength2();
263 scinInfo2->dy1 = trd2->getYHalfLength1();
264 scinInfo2->dy2 = trd2->getYHalfLength2();
265 scinInfo2->dz = trd2->getZHalfLength();
266 scinInfo2->aTransforms = aTransforms2;
267 scinInfo2->cTransforms = cTransforms2;
268
269
270 m_clockwork->scinInfoMap[0] = scinInfo1;
271 m_clockwork->scinInfoMap[1] = scinInfo2;
272}
273
275{
276 // This method is called only once per event
277 // It does not actually build anything for 3D scene
278 // The method retrieves MBTS Container and builds corresponding VP1Mbts objects
279 m_clockwork->separator = root;
280
281 StatusCode status = sg->retrieve(m_clockwork->mbts_container,"MBTSContainer");
282 if(status.isFailure() || m_clockwork->mbts_container == 0)
283 {
284 m_clockwork->mbts_container = 0;
285 throw std::runtime_error("Unable to retrieve MBTS Container");
286 }
287
288 for (const TileCell* cell : *m_clockwork->mbts_container)
289 {
290 VP1Mbts* mbts = new VP1Mbts(cell,m_clockwork->tiletb_id,root,m_run2Geo);
291 m_clockwork->vp1_mbts.push_back(mbts);
292 }
293}
294
296{
297 if(m_clockwork->separator)
298 m_clockwork->separator->removeAllChildren();
299 m_clockwork->node2mbtsMap.clear();
300
301 // Clear VP1Mbts vector
302 for(size_t ii=0; ii < m_clockwork->vp1_mbts.size(); ii++)
303 delete m_clockwork->vp1_mbts[ii];
304 m_clockwork->vp1_mbts.clear();
305
306 m_clockwork->mbts_container = 0;
307 m_clockwork->separator = 0;
308
309}
310
312{
313 // Remove all previously created objects
314 if(m_clockwork->separator)
315 m_clockwork->separator->removeAllChildren();
316 m_clockwork->node2mbtsMap.clear();
317
318 // Loop over all VP1Mbts elements
319 if(!interval.isEmpty())
320 for(size_t i=0; i<m_clockwork->vp1_mbts.size(); i++)
321 m_clockwork->vp1_mbts[i]->UpdateScene(&m_clockwork->scinInfoMap, &m_clockwork->node2mbtsMap, interval.lower(),m_outline, m_clipRadius);
322}
323
325 m_clockwork->controller = controller;
326}
327
329{
330 std::cout<<" clipVolumeRadiusChanged to "<<radius<<std::endl;
331 m_clipRadius=radius; // Adjust radius to match new value
332 refreshGraph(m_clockwork->controller->selectionMbts());
333}
334
335std::vector<std::string> VP1MbtsHelper::userPickedNode(SoNode* pickedNode)
336{
337 // std::cout << "VP1MbtsHelper::userPickedNode()..." << std::endl;
338
339 std::vector<std::string> result;
340 VP1CC_SoNode2MbtsMap::iterator it = m_clockwork->node2mbtsMap.find(pickedNode);
341 if(it!=m_clockwork->node2mbtsMap.end())
342 result = it->second->ToString();
343
344 return result;
345}
346
348{
349 refreshGraph(interval);
350}
351
352void VP1MbtsHelper::outlineUpdate(const bool& outline)
353{
354 m_outline = outline;
355 VP1CC_SoNode2MbtsMap::iterator it = m_clockwork->node2mbtsMap.begin();
356 for(; it!=m_clockwork->node2mbtsMap.end(); ++it) {
357 SoGenericBox* genBox = dynamic_cast<SoGenericBox*>(it->first);
358 if(genBox)
359 genBox->drawEdgeLines = m_outline;
360 }
361}
TileContainer< TileCell > TileCellContainer
std::map< int, VP1CC_MbtsScinInfo *, std::less< int > > VP1CC_MbtsScinInfoMap
std::map< SoNode *, VP1Mbts *, std::less< SoNode * > > VP1CC_SoNode2MbtsMap
std::map< int, GeoTrf::Transform3D, std::less< int > > VP1CC_MbtsXfMap
SoSFBool drawEdgeLines
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
GeoFullPhysVol * getPhysVol()
Destructor.
Helper class for TileCal offline identifiers of ancillary testbeam detectors and MBTS.
VP1CaloCellController * controller
VP1CC_SoNode2MbtsMap node2mbtsMap
VP1CC_MbtsScinInfoMap scinInfoMap
const TileTBID * tiletb_id
std::vector< VP1Mbts * > vp1_mbts
const TileCellContainer * mbts_container
double m_clipRadius
std::vector< std::string > userPickedNode(SoNode *pickedNode)
void buildEventSceneGraph(StoreGateSvc *sg, SoSeparator *root)
void systemcreate(StoreGateSvc *detstore)
void selectionUpdated(const VP1Interval &interval)
VP1MbtsHelper(bool outline)
void refreshGraph(const VP1Interval &interval)
void clipVolumeRadiusChanged(double radius)
Clockwork * m_clockwork
void outlineUpdate(const bool &outline)
void setController(VP1CaloCellController *)
VP1CC_MbtsXfMap cTransforms
VP1CC_MbtsXfMap aTransforms