ATLAS Offline Software
Loading...
Searching...
No Matches
FCALConstruction.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "LArReadoutGeometry/FCAL_ChannelMap.h"
7
8#include "GeoModelKernel/GeoMaterial.h"
9#include "GeoModelKernel/GeoFullPhysVol.h"
10#include "GeoModelKernel/GeoPhysVol.h"
11#include "GeoModelKernel/GeoLogVol.h"
12#include "GeoModelKernel/GeoTransform.h"
13#include "GeoModelKernel/GeoAlignableTransform.h"
14#include "GeoModelKernel/GeoIdentifierTag.h"
15#include "GeoModelKernel/GeoSerialIdentifier.h"
16#include "GeoModelKernel/GeoSerialTransformer.h"
17#include "GeoModelKernel/GeoXF.h"
18
19// volumes used: Pcon, Tubs, Cons, Box, Trap
20#include "GeoModelKernel/GeoPcon.h"
21#include "GeoModelKernel/GeoTubs.h"
22#include "GeoModelKernel/GeoCons.h"
23#include "GeoModelKernel/GeoBox.h"
24#include "GeoModelKernel/GeoTrap.h"
25#include "GeoModelKernel/GeoDefinitions.h"
33
34// For functions:
35#include "GeoGenericFunctions/Variable.h"
36#include "GeoGenericFunctions/ArrayFunction.h"
37
42
43#include "GaudiKernel/ISvcLocator.h"
44#include "GaudiKernel/MsgStream.h"
45#include "GaudiKernel/Bootstrap.h"
46#include "GaudiKernel/SystemOfUnits.h"
47#include <string>
48#include <cmath>
49#include <cfloat>
50#include <sstream>
51#include <fstream>
52#include <stdexcept>
53
54//================== get envelope
55GeoIntrusivePtr<GeoVFullPhysVol> LArGeo::FCALConstruction::GetEnvelope(bool bPos)
56{
57 IRDBAccessSvc* rdbAccess{nullptr};
58 IGeoModelSvc * geoModel{nullptr};
59
60 if(!m_absPhysical1) {
61 // Access Geometry DB
62 m_svcLocator = Gaudi::svcLocator();
63
64 SmartIF<IGeoModelSvc> gModel{m_svcLocator->service("GeoModelSvc")};
65 if(!gModel.isValid()) {
66 throw std::runtime_error("Error in FCALConstruction, cannot access GeoModelSvc");
67 }
68 geoModel = gModel.get();
69 SmartIF<IRDBAccessSvc> rAccess{m_svcLocator->service("RDBAccessSvc")};
70 if(!rAccess.isValid()) {
71 throw std::runtime_error("Error in FCALConstruction, cannot access RDBAccessSvc");
72 }
73 rdbAccess = rAccess.get();
74 DecodeVersionKey larVersionKey(geoModel, "LAr");
75
76 m_fcalMod = rdbAccess->getRecordsetPtr("FCalMod", larVersionKey.tag(),larVersionKey.node());
77 if (m_fcalMod->size()==0) {
78 m_fcalMod=rdbAccess->getRecordsetPtr("FCalMod", "FCalMod-00");
79 if (m_fcalMod->size()==0) {
80 throw std::runtime_error("Error getting FCAL Module parameters from database");
81 }
82 }
83
84 m_LArPosition = rdbAccess->getRecordsetPtr("LArPosition", larVersionKey.tag(), larVersionKey.node());
85 if (m_LArPosition->size()==0 ) {
86 m_LArPosition = rdbAccess->getRecordsetPtr("LArPosition", "LArPosition-00");
87 if (m_LArPosition->size()==0 ) {
88 throw std::runtime_error("Error, no lar position table in database!");
89 }
90 }
91
92 }
93
94 // Flags to turn on volumes.
95 const bool F1=true,F2=true,F3=true;
96
97 SmartIF<StoreGateSvc> detStore{m_svcLocator->service("DetectorStore")};
98 if(!detStore.isValid()) {
99 throw std::runtime_error("Error in FCALConstruction, cannot access DetectorStore");
100 }
101
102 StoredMaterialManager* materialManager = nullptr;
103 if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
104
105 const GeoMaterial *Copper = materialManager->getMaterial("std::Copper");
106 if (!Copper) throw std::runtime_error("Error in FCALConstruction, std::Copper is not found.");
107
108 const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
109 if (!Iron) throw std::runtime_error("Error in FCALConstruction, std::Iron is not found.");
110
111 const GeoMaterial *Lead = materialManager->getMaterial("std::Lead");
112 if (!Lead) throw std::runtime_error("Error in FCALConstruction, std::Lead is not found.");
113
114 const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
115 if (!LAr) throw std::runtime_error("Error in FCALConstruction, std::LiquidArgon is not found.");
116
117 const GeoMaterial *Air = materialManager->getMaterial("std::Air");
118 if (!Air) throw std::runtime_error("Error in FCALConstruction, std::Air is not found.");
119
120 const GeoMaterial *Kapton = materialManager->getMaterial("std::Kapton");
121 if (!Kapton) throw std::runtime_error("Error in FCALConstruction, std::Kapton is not found.");
122
123 const GeoMaterial *Glue = materialManager->getMaterial("LAr::Glue");
124 if (!Glue) throw std::runtime_error("Error in FCALConstruction, LAr::Glue is not found.");
125
126 const GeoMaterial *G10 = materialManager->getMaterial("LAr::G10");
127 if (!G10) throw std::runtime_error("Error in FCALConstruction, LAr::G10 is not found.");
128
129
130 const GeoMaterial *FCal1Absorber = materialManager->getMaterial("LAr::FCal1Absorber");
131 if (!FCal1Absorber) throw std::runtime_error("Error in FCALConstruction, LAr::FCal1Absorber is not found.");
132
133 const GeoMaterial *FCal23Absorber = materialManager->getMaterial("LAr::FCal23Absorber");
134 if (!FCal23Absorber) throw std::runtime_error("Error in FCALConstruction, LAr::FCal23Absorber is not found.");
135
136 const GeoMaterial *FCalCableHarness = materialManager->getMaterial("LAr::FCalCableHarness");
137 if (!FCalCableHarness) throw std::runtime_error("Error in FCALConstruction, LAr::FCalCableHarness is not found.");
138
139 const GeoMaterial *FCal23Slugs = materialManager->getMaterial("LAr::FCal23Slugs");
140 if (!FCal23Slugs) throw std::runtime_error("Error in FCALConstruction, LAr::FCal23Slugs is not found.");
141
142
143 auto cmap = std::make_unique<FCAL_ChannelMap>(0);
144
145 GeoIntrusivePtr<GeoFullPhysVol> fcalPhysical{nullptr};
146
147 std::string baseName = "LAr::FCAL::";
148
149 double startZFCal1 = (*m_fcalMod)[0]->getDouble("STARTPOSITION"); //466.85 * cm;
150 //double startZFCal2 = (*m_fcalMod)[1]->getDouble("STARTPOSITION"); //512.83 * cm;
151 double startZFCal3 = (*m_fcalMod)[2]->getDouble("STARTPOSITION"); //560.28 * cm;
152
153 double outerModuleRadius1=(*m_fcalMod)[0]->getDouble("OUTERMODULERADIUS");
154 double outerModuleRadius2=(*m_fcalMod)[1]->getDouble("OUTERMODULERADIUS");
155 double outerModuleRadius3=(*m_fcalMod)[2]->getDouble("OUTERMODULERADIUS");
156 double innerModuleRadius1=(*m_fcalMod)[0]->getDouble("INNERMODULERADIUS");
157 double innerModuleRadius2=(*m_fcalMod)[1]->getDouble("INNERMODULERADIUS");
158 double innerModuleRadius3=(*m_fcalMod)[2]->getDouble("INNERMODULERADIUS");
159 double fullModuleDepth1=(*m_fcalMod)[0]->getDouble("FULLMODULEDEPTH");
160 double fullModuleDepth2=(*m_fcalMod)[1]->getDouble("FULLMODULEDEPTH");
161 double fullModuleDepth3=(*m_fcalMod)[2]->getDouble("FULLMODULEDEPTH");
162 double fullGapDepth1=(*m_fcalMod)[0]->getDouble("FULLGAPDEPTH");
163 double fullGapDepth2=(*m_fcalMod)[1]->getDouble("FULLGAPDEPTH");
164 double fullGapDepth3=(*m_fcalMod)[2]->getDouble("FULLGAPDEPTH");
165 double outerGapRadius1=(*m_fcalMod)[0]->getDouble("OUTERGAPRADIUS");
166 double outerGapRadius2=(*m_fcalMod)[1]->getDouble("OUTERGAPRADIUS");
167 double outerGapRadius3=(*m_fcalMod)[2]->getDouble("OUTERGAPRADIUS");
168 double innerGapRadius1=(*m_fcalMod)[0]->getDouble("INNERGAPRADIUS");
169 double innerGapRadius2=(*m_fcalMod)[1]->getDouble("INNERGAPRADIUS");
170 double innerGapRadius3=(*m_fcalMod)[2]->getDouble("INNERGAPRADIUS");
171
172
173 // FCAL VOLUME. IT DOES NOT INCLUDE THE COPPER PLUG, ONLY THE LAR AND MODS 1-3
174 {
175
176 double outerRadius = std::max(outerModuleRadius1,std::max(outerModuleRadius2,outerModuleRadius3));
177 double innerRadius = std::min(innerModuleRadius1,std::min(innerModuleRadius2,innerModuleRadius3));
178 double depthZFCal3 = fullModuleDepth3;
179 double stopZFCal3 = startZFCal3 + depthZFCal3;
180
181 double totalDepth = stopZFCal3 - startZFCal1;
182 double halfDepth = totalDepth/2.;
183
184 std::string name = baseName + "LiquidArgonC";
185 GeoTubs *tubs = new GeoTubs(innerRadius,outerRadius,halfDepth,0,360*Gaudi::Units::deg);
186 GeoLogVol *logVol= new GeoLogVol(name, tubs, LAr);
187 fcalPhysical = new GeoFullPhysVol(logVol);
188 }
189
190
191
192 if (F1)
193 {
194
195 // Module 1
196 GeoIntrusivePtr<GeoFullPhysVol> modPhysical{nullptr};
197 {
198 double halfDepth = fullModuleDepth1/2;
199 double innerRadius = innerModuleRadius1;
200 double outerRadius = outerModuleRadius1;
201 GeoIntrusivePtr<GeoFullPhysVol>physVol;
202
203 if(m_absPhysical1) {
204 physVol = m_absPhysical1->clone();
205 }
206 else {
207 GeoTubs *tubs = new GeoTubs( innerRadius, outerRadius, halfDepth, 0, 2*M_PI);
208 GeoLogVol *logVol = new GeoLogVol(baseName + "Module1::Absorber", tubs, FCal1Absorber);
209 physVol = new GeoFullPhysVol(logVol);
210 }
211
212 // Alignable transform
213
214 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(m_LArPosition, bPos ? "FCAL1_POS":"FCAL1_NEG");
215 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
216 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
217 GeoAlignableTransform *xfAbs1 = new GeoAlignableTransform(xfPos);
218
219 fcalPhysical->add(xfAbs1);
220 if (!bPos) fcalPhysical->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::deg)));
221 fcalPhysical->add(physVol);
222 modPhysical = physVol;
223
224 std::string tag = bPos? std::string("FCAL1_POS") : std::string("FCAL1_NEG");
225 StatusCode status;
226
227 StoredPhysVol *sPhysVol = new StoredPhysVol(physVol);
228 status=detStore->record(sPhysVol,tag);
229 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
230
231 StoredAlignX *sAlignX = new StoredAlignX(xfAbs1);
232 status=detStore->record(sAlignX,tag);
233 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
234
235 }
236 // 16 Troughs representing Cable Harnesses:
237 if(m_fullGeo && !m_absPhysical1) {
238 double troughDepth = 1.0 * Gaudi::Units::cm;
239 double outerRadius = outerModuleRadius1;
240 double innerRadius = outerRadius - troughDepth;
241 double halfLength = fullModuleDepth1/ 2.0;
242 double deltaPhi = 5.625 * Gaudi::Units::deg;
243 double startPhi = 11.25 * Gaudi::Units::deg - deltaPhi/2.0;
244 GeoTubs * tubs = new GeoTubs(innerRadius,outerRadius,halfLength,startPhi,deltaPhi );
245 GeoLogVol *logVol = new GeoLogVol(baseName+"Module1::CableTrough",tubs,FCalCableHarness);
246 GeoIntrusivePtr<GeoPhysVol>physVol = new GeoPhysVol(logVol);
247 GeoGenfun::Variable i;
248 GeoGenfun::GENFUNCTION rotationAngle = 22.5*Gaudi::Units::deg*i;
249 GeoXF::TRANSFUNCTION xf = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),rotationAngle);
250 GeoSerialTransformer *st = new GeoSerialTransformer(physVol,&xf,16);
251 modPhysical->add(st);
252 }
253
254 if(!m_absPhysical1) {
255 double halfDepth = fullGapDepth1/2.0;
256 double innerRadius = innerGapRadius1;
257 double outerRadius = outerGapRadius1;
258 GeoIntrusivePtr<GeoPhysVol>physVol{nullptr};
259 if(m_fullGeo) {
260 GeoTubs *tubs = new GeoTubs(innerRadius,outerRadius,halfDepth,0.0, 2.0*M_PI);
261 GeoLogVol *logVol = new GeoLogVol(baseName + "Module1::Gap",tubs, LAr);
262 physVol = new GeoPhysVol(logVol);
263 modPhysical->add(new GeoSerialIdentifier(0));
264 }
265
266 int counter=0;
267 // Electrodes:
268 int myGroup=1;
269
270 // Field names
271 unsigned fieldModNumber(2); //std::string fieldModNumber("LARFCALELECTRODES_DATA.MODNUMBER");
272 unsigned fieldTileName(1); //std::string fieldTileName("LARFCALELECTRODES_DATA.TILENAME");
273 unsigned fieldI(4); //std::string fieldI("LARFCALELECTRODES_DATA.I");
274 unsigned fieldJ(5); //std::string fieldJ("LARFCALELECTRODES_DATA.J");
275 unsigned fieldId(3); //std::string fieldId("LARFCALELECTRODES_DATA.ID");
276 unsigned fieldX(6); //std::string fieldX("LARFCALELECTRODES_DATA.X");
277 unsigned fieldY(7); //std::string fieldY("LARFCALELECTRODES_DATA.Y");
278 unsigned fieldHvFt(8); //std::string fieldHvFt("LARFCALELECTRODES_DATA.HVFEEDTHROUGHID");
279
280 std::unique_ptr<IRDBQuery> query;
281 DecodeVersionKey larVersionKey(geoModel, "LAr");
282 query = rdbAccess->getQuery("LArFCalElectrodes", larVersionKey.tag(),larVersionKey.node());
283 if(!query) {
284 query = rdbAccess->getQuery("LArFCalElectrodes", "LArFCalElectrodes-00");
285 if(!query)
286 throw std::runtime_error("Error getting Session and Query pointers");
287 }
288 query->execute();
289 if(query->size()==0)
290 throw std::runtime_error("Error, unable to fetch fcal electrodes from the database!");
291
292
293 while(query->next()) {
294
295 if(myGroup!=query->data<int>(fieldModNumber)) continue;
296
297// std::string thisTileStr=row["LARFCALELECTRODES_DATA.TILENAME"].data<std::string>();
298 int thisTubeI=query->data<int>(fieldI);
299 int thisTubeJ= query->data<int>(fieldJ);
300 int thisTubeID = query->data<int>(fieldId);
301 int thisTubeMod = myGroup;
302 double thisTubeX= query->data<double>(fieldX);
303 double thisTubeY= query->data<double>(fieldY);
304// std::string thisHVft=row["LARFCALELECTRODES_DATA.HVFEEDTHROUGHID"].data<std::string>();
305
306 cmap->add_tube(query->data<std::string>(fieldTileName),
307 thisTubeMod, thisTubeID, thisTubeI,thisTubeJ, thisTubeX, thisTubeY,
308 query->data<std::string>(fieldHvFt));
309
310 if (m_VisLimit != -1 && (counter++ > m_VisLimit)) continue;
311 if(m_fullGeo) {
312 GeoTransform *xf = new GeoTransform(GeoTrf::Translate3D(thisTubeX*Gaudi::Units::cm, thisTubeY*Gaudi::Units::cm,0));
313 modPhysical->add(xf);
314 modPhysical->add(physVol);
315 }
316 }
317
318 m_absPhysical1 = modPhysical;
319 query->finalize();
320 }
321 } // if (F1)
322 if (F2)
323 {
324 // Module 2
325 GeoIntrusivePtr<GeoFullPhysVol> modPhysical{nullptr};
326 {
327 double halfDepth = fullModuleDepth2/2;
328 double innerRadius = innerModuleRadius2;
329 double outerRadius = outerModuleRadius2;
330 GeoIntrusivePtr<GeoFullPhysVol>physVol;
331
332 if(m_absPhysical2) {
333 physVol = m_absPhysical2->clone();
334 }
335 else {
336 GeoTubs *tubs = new GeoTubs( innerRadius, outerRadius, halfDepth, 0, 2*M_PI);
337 GeoLogVol *logVol = new GeoLogVol(baseName + "Module2::Absorber", tubs, FCal23Absorber);
338 physVol = new GeoFullPhysVol(logVol);
339 }
340
341 // Alignable transform
342
343 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(m_LArPosition, bPos ? "FCAL2_POS":"FCAL2_NEG");
344 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
345 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
346 GeoAlignableTransform *xfAbs2 = new GeoAlignableTransform(xfPos);
347
348 fcalPhysical->add(xfAbs2);
349 if (!bPos) fcalPhysical->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::deg)));
350 fcalPhysical->add(physVol);
351 modPhysical = physVol;
352
353 std::string tag = bPos? std::string("FCAL2_POS") : std::string("FCAL2_NEG");
354 StatusCode status;
355
356 StoredPhysVol *sPhysVol = new StoredPhysVol(physVol);
357 status=detStore->record(sPhysVol,tag);
358 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
359
360 StoredAlignX *sAlignX = new StoredAlignX(xfAbs2);
361 status=detStore->record(sAlignX,tag);
362 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
363
364 }
365 // 16 Troughs representing Cable Harnesses:
366 if(m_fullGeo && !m_absPhysical2) {
367 double troughDepth = 1.0 * Gaudi::Units::cm;
368 double outerRadius = outerModuleRadius2;
369 double innerRadius = outerRadius - troughDepth;
370 double halfLength = fullModuleDepth2/ 2.0;
371 double deltaPhi = 5.625 * Gaudi::Units::deg;
372 double startPhi = 11.25 * Gaudi::Units::deg - deltaPhi/2.0;
373 GeoTubs * tubs = new GeoTubs(innerRadius,outerRadius,halfLength,startPhi,deltaPhi );
374 GeoLogVol *logVol = new GeoLogVol(baseName+"Module2::CableTrough",tubs,FCalCableHarness);
375 GeoIntrusivePtr<GeoPhysVol>physVol = new GeoPhysVol(logVol);
376 GeoGenfun::Variable i;
377 GeoGenfun::GENFUNCTION rotationAngle = 22.5*Gaudi::Units::deg*i;
378 GeoXF::TRANSFUNCTION xf = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),rotationAngle);
379 GeoSerialTransformer *st = new GeoSerialTransformer(physVol,&xf,16);
380 modPhysical->add(st);
381 }
382
383 // Electrodes:
384 if(!m_absPhysical2) {
385 double halfDepth = fullGapDepth2/2.0;
386 double innerRadius = innerGapRadius2;
387 double outerRadius = outerGapRadius2;
388
389 GeoIntrusivePtr<GeoPhysVol> gapPhys{nullptr};
390 GeoIntrusivePtr<GeoPhysVol> rodPhys{nullptr};
391 if(m_fullGeo) {
392 GeoTubs *gapTubs = new GeoTubs(0,outerRadius,halfDepth,0.0, 2.0*M_PI);
393 GeoLogVol *gapLog = new GeoLogVol(baseName + "Module2::Gap",gapTubs, LAr);
394 gapPhys = new GeoPhysVol(gapLog);
395
396 GeoTubs *rodTubs = new GeoTubs(0,innerRadius,halfDepth,0.0, 2.0*M_PI);
397 GeoLogVol *rodLog = new GeoLogVol(baseName + "Module2::Rod",rodTubs, FCal23Slugs);
398 rodPhys = new GeoPhysVol(rodLog);
399 gapPhys->add(rodPhys);
400 modPhysical->add(new GeoSerialIdentifier(0));
401 }
402
403 int counter=0;
404
405 int myGroup=2;
406
407 // Field names
408 unsigned fieldModNumber(2); //std::string fieldModNumber("LARFCALELECTRODES_DATA.MODNUMBER");
409 unsigned fieldTileName(1); //std::string fieldTileName("LARFCALELECTRODES_DATA.TILENAME");
410 unsigned fieldI(4); //std::string fieldI("LARFCALELECTRODES_DATA.I");
411 unsigned fieldJ(5); //std::string fieldJ("LARFCALELECTRODES_DATA.J");
412 unsigned fieldId(3); //std::string fieldId("LARFCALELECTRODES_DATA.ID");
413 unsigned fieldX(6); //std::string fieldX("LARFCALELECTRODES_DATA.X");
414 unsigned fieldY(7); //std::string fieldY("LARFCALELECTRODES_DATA.Y");
415 unsigned fieldHvFt(8); //std::string fieldHvFt("LARFCALELECTRODES_DATA.HVFEEDTHROUGHID");
416
417 std::unique_ptr<IRDBQuery> query;
418 DecodeVersionKey larVersionKey(geoModel, "LAr");
419 query = rdbAccess->getQuery("LArFCalElectrodes", larVersionKey.tag(),larVersionKey.node());
420 if(!query) {
421 query = rdbAccess->getQuery("LArFCalElectrodes", "LArFCalElectrodes-00");
422 if(!query)
423 throw std::runtime_error("Error getting Session and Query pointers");
424 }
425 query->execute();
426 if(query->size()==0)
427 throw std::runtime_error("Error, unable to fetch fcal electrodes from the database!");
428
429 while(query->next()) {
430
431 if(myGroup!=query->data<int>(fieldModNumber)) continue;
432
433
434// std::string thisTileStr=row["LARFCALELECTRODES_DATA.TILENAME"].data<std::string>();
435 int thisTubeI=query->data<int>(fieldI);
436 int thisTubeJ= query->data<int>(fieldJ);
437 int thisTubeID = query->data<int>(fieldId);
438 int thisTubeMod = myGroup;
439 double thisTubeX= query->data<double>(fieldX);
440 double thisTubeY= query->data<double>(fieldY);
441// std::string thisHVft=row["LARFCALELECTRODES_DATA.HVFEEDTHROUGHID"].data<std::string>();
442
443 cmap->add_tube(query->data<std::string>(fieldTileName),
444 thisTubeMod, thisTubeID, thisTubeI,thisTubeJ, thisTubeX, thisTubeY,
445 query->data<std::string>(fieldHvFt));
446
447 if (m_VisLimit != -1 && (counter++ > m_VisLimit)) continue;
448 if(m_fullGeo) {
449 GeoTransform *xf = new GeoTransform(GeoTrf::Translate3D(thisTubeX*Gaudi::Units::cm, thisTubeY*Gaudi::Units::cm,0));
450 modPhysical->add(xf);
451 modPhysical->add(gapPhys);
452 }
453 }
454
455 m_absPhysical2 = modPhysical;
456 query->finalize();
457 }
458 } // if (F2)
459
460 if (F3)
461 {
462 // Module 3
463 GeoIntrusivePtr<GeoFullPhysVol> modPhysical{nullptr};
464 {
465 double halfDepth = fullModuleDepth3/2;
466 double innerRadius = innerModuleRadius3;
467 double outerRadius = outerModuleRadius3;
468 GeoIntrusivePtr<GeoFullPhysVol>physVol;
469
470 if(m_absPhysical3) {
471 physVol = m_absPhysical3->clone();
472 }
473 else {
474 GeoTubs *tubs = new GeoTubs( innerRadius, outerRadius, halfDepth, 0, 2*M_PI);
475 GeoLogVol *logVol = new GeoLogVol(baseName + "Module3::Absorber", tubs, FCal23Absorber);
476 physVol = new GeoFullPhysVol(logVol);
477 }
478
479 // Alignable transform
480 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(m_LArPosition, bPos ? "FCAL3_POS":"FCAL3_NEG");
481 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
482 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
483 GeoAlignableTransform *xfAbs3 = new GeoAlignableTransform(xfPos);
484
485 fcalPhysical->add(xfAbs3);
486 if (!bPos) fcalPhysical->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::deg)));
487 fcalPhysical->add(physVol);
488 modPhysical = physVol;
489
490 std::string tag = bPos? std::string("FCAL3_POS") : std::string("FCAL3_NEG");
491 StatusCode status;
492
493 StoredPhysVol *sPhysVol = new StoredPhysVol(physVol);
494 status=detStore->record(sPhysVol,tag);
495 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
496
497 StoredAlignX *sAlignX = new StoredAlignX(xfAbs3);
498 status=detStore->record(sAlignX,tag);
499 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
500
501
502 }
503 // 16 Troughs representing Cable Harnesses:
504 if(m_fullGeo && !m_absPhysical3) {
505 static const double rotAngles[] =
506 { 11.25 * Gaudi::Units::deg,
507 22.50 * Gaudi::Units::deg,
508 45.00 * Gaudi::Units::deg,
509 56.25 * Gaudi::Units::deg,
510 67.50 * Gaudi::Units::deg,
511 90.00 * Gaudi::Units::deg, // first quarter
512 101.25 * Gaudi::Units::deg,
513 112.50 * Gaudi::Units::deg,
514 135.00 * Gaudi::Units::deg,
515 146.25 * Gaudi::Units::deg,
516 157.50 * Gaudi::Units::deg,
517 180.00 * Gaudi::Units::deg, // second quarter
518 191.25 * Gaudi::Units::deg,
519 202.50 * Gaudi::Units::deg,
520 225.00 * Gaudi::Units::deg,
521 236.25 * Gaudi::Units::deg,
522 247.50 * Gaudi::Units::deg,
523 270.00 * Gaudi::Units::deg, // third quarter
524 281.25 * Gaudi::Units::deg,
525 292.50 * Gaudi::Units::deg,
526 315.00 * Gaudi::Units::deg,
527 326.25 * Gaudi::Units::deg,
528 337.50 * Gaudi::Units::deg,
529 360.00 * Gaudi::Units::deg };
530
531 GeoGenfun::ArrayFunction rotationAngle(rotAngles,rotAngles+24);
532 double troughDepth = 1.0 * Gaudi::Units::cm;
533 double outerRadius = outerModuleRadius3;
534 double innerRadius = outerRadius - troughDepth;
535 double halfLength = fullModuleDepth3/ 2.0;
536 double deltaPhi = 5.625 * Gaudi::Units::deg;
537 double startPhi = 11.25 * Gaudi::Units::deg - deltaPhi/2.0;
538 GeoTubs * tubs = new GeoTubs(innerRadius,outerRadius,halfLength,startPhi,deltaPhi );
539 GeoLogVol *logVol = new GeoLogVol(baseName+"Module3::CableTrough",tubs,FCalCableHarness);
540 GeoIntrusivePtr<GeoPhysVol>physVol = new GeoPhysVol(logVol);
541 GeoXF::TRANSFUNCTION xf = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),rotationAngle);
542 GeoSerialTransformer *st = new GeoSerialTransformer(physVol,&xf,24);
543 modPhysical->add(st);
544 }
545
546 // Electrodes:
547 if(!m_absPhysical3) {
548 double halfDepth = fullGapDepth3/2.0;
549 double innerRadius = innerGapRadius3;
550 double outerRadius = outerGapRadius3;
551
552 GeoIntrusivePtr<GeoPhysVol> gapPhys{nullptr};
553 GeoIntrusivePtr<GeoPhysVol> rodPhys{nullptr};
554 if(m_fullGeo) {
555 GeoTubs *gapTubs = new GeoTubs(0,outerRadius,halfDepth,0.0, 2.0*M_PI);
556 GeoLogVol *gapLog = new GeoLogVol(baseName + "Module3::Gap",gapTubs, LAr);
557 gapPhys = new GeoPhysVol(gapLog);
558
559 GeoTubs *rodTubs = new GeoTubs(0,innerRadius,halfDepth,0.0, 2.0*M_PI);
560 GeoLogVol *rodLog = new GeoLogVol(baseName + "Module3::Rod",rodTubs, FCal23Slugs);
561 rodPhys = new GeoPhysVol(rodLog);
562 gapPhys->add(rodPhys);
563 modPhysical->add(new GeoSerialIdentifier(0));
564 }
565
566 int counter=0;
567
568 int myGroup=3;
569
570 // Field names
571 unsigned fieldModNumber(2); //std::string fieldModNumber("LARFCALELECTRODES_DATA.MODNUMBER");
572 unsigned fieldTileName(1); //std::string fieldTileName("LARFCALELECTRODES_DATA.TILENAME");
573 unsigned fieldI(4); //std::string fieldI("LARFCALELECTRODES_DATA.I");
574 unsigned fieldJ(5); //std::string fieldJ("LARFCALELECTRODES_DATA.J");
575 unsigned fieldId(3); //std::string fieldId("LARFCALELECTRODES_DATA.ID");
576 unsigned fieldX(6); //std::string fieldX("LARFCALELECTRODES_DATA.X");
577 unsigned fieldY(7); //std::string fieldY("LARFCALELECTRODES_DATA.Y");
578 unsigned fieldHvFt(8); //std::string fieldHvFt("LARFCALELECTRODES_DATA.HVFEEDTHROUGHID");
579
580 std::unique_ptr<IRDBQuery> query;
581 DecodeVersionKey larVersionKey(geoModel, "LAr");
582 query = rdbAccess->getQuery("LArFCalElectrodes", larVersionKey.tag(),larVersionKey.node());
583 if(!query) {
584 query = rdbAccess->getQuery("LArFCalElectrodes", "LArFCalElectrodes-00");
585 if(!query)
586 throw std::runtime_error("Error getting Session and Query pointers");
587 }
588 query->execute();
589 if(query->size()==0)
590 throw std::runtime_error("Error, unable to fetch fcal electrodes from the database!");
591
592 while(query->next()) {
593
594 if(myGroup!=query->data<int>(fieldModNumber)) continue;
595
596// std::string thisTileStr=row["LARFCALELECTRODES_DATA.TILENAME"].data<std::string>();
597 int thisTubeI=query->data<int>(fieldI);
598 int thisTubeJ= query->data<int>(fieldJ);
599 int thisTubeID = query->data<int>(fieldId);
600 int thisTubeMod = myGroup;
601 double thisTubeX= query->data<double>(fieldX);
602 double thisTubeY= query->data<double>(fieldY);
603// std::string thisHVft=row["LARFCALELECTRODES_DATA.HVFEEDTHROUGHID"].data<std::string>();
604
605 cmap->add_tube(query->data<std::string>(fieldTileName),
606 thisTubeMod, thisTubeID, thisTubeI,thisTubeJ, thisTubeX, thisTubeY,
607 query->data<std::string>(fieldHvFt));
608
609 if (m_VisLimit != -1 && (counter++ > m_VisLimit)) continue;
610 if(m_fullGeo) {
611 GeoTransform *xf = new GeoTransform(GeoTrf::Translate3D(thisTubeX*Gaudi::Units::cm, thisTubeY*Gaudi::Units::cm,0));
612 modPhysical->add(xf);
613 modPhysical->add(gapPhys);
614 }
615 }
616
617 m_absPhysical3 = modPhysical;
618 query->finalize();
619 }
620 } // if (F3)
621
622 // Did I already store it?
623 //FCAL_ChannelMap *aChannelMap(NULL);
624 // if (detStore->retrieve(aChannelMap)==StatusCode::FAILURE) {
625 if (!detStore->contains<FCAL_ChannelMap>("FCAL_ChannelMap")) {
626 cmap->finish();
627 StatusCode status=detStore->record(std::move(cmap),"FCAL_ChannelMap");
628 if(!status.isSuccess()) throw std::runtime_error ("Cannot store FCAL_ChannelMap");
629 }
630
631 return fcalPhysical;
632}
#define M_PI
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Definition of the abstract IRDBAccessSvc interface.
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
const std::string & tag() const
Return version tag.
const std::string & node() const
Return the version node.
This class contains the tube and tile maps for the FCAL A tile is of a set of FCAL tubes.
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition GeoDBUtils.h:23
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition GeoDBUtils.h:33
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
virtual IRDBRecordset_ptr getRecordsetPtr(const std::string &node, const std::string &tag, const std::string &tag2node="", const std::string &connName="ATLASDD")=0
Provides access to the Recordset object containing HVS-tagged data.
virtual std::unique_ptr< IRDBQuery > getQuery(const std::string &node, const std::string &tag, const std::string &tag2node="", const std::string &connName="ATLASDD")=0
IRDBRecord is one record in the IRDBRecordset object.
Definition IRDBRecord.h:27
GeoIntrusivePtr< GeoFullPhysVol > m_absPhysical2
IRDBRecordset_ptr m_LArPosition
GeoIntrusivePtr< GeoVFullPhysVol > GetEnvelope(bool bPos)
GeoIntrusivePtr< GeoFullPhysVol > m_absPhysical3
GeoIntrusivePtr< GeoFullPhysVol > m_absPhysical1
IRDBRecordset_ptr m_fcalMod
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
Definition query.py:1