ATLAS Offline Software
Loading...
Searching...
No Matches
ForwardRegionGeoModelFactory.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#include "GeoModelKernel/GeoMaterial.h"
7#include "GeoModelKernel/GeoBox.h"
8#include "GeoModelKernel/GeoTube.h"
9#include "GeoModelKernel/GeoShapeSubtraction.h"
10#include "GeoModelKernel/GeoShapeUnion.h"
11#include "GeoModelKernel/GeoShapeShift.h"
12#include "GeoModelKernel/GeoLogVol.h"
13#include "GeoModelKernel/GeoNameTag.h"
14#include "GeoModelKernel/GeoPhysVol.h"
15#include "GeoModelKernel/GeoDefinitions.h"
16#include "GeoModelKernel/Units.h"
18#include "CLHEP/Geometry/Point3D.h"
20#include "GaudiKernel/SystemOfUnits.h"
21
23
24#include <iostream>
25#include <sstream>
26#include <fstream>
27#include <math.h> //for abs, tan, atan2
28
29#include <stdlib.h>// for atof
30
31
33{
34 TCL4JawDistB1I = 57*Gaudi::Units::mm;
35 TCL5JawDistB1I = 57*Gaudi::Units::mm;
36 TCL6JawDistB1I = 57*Gaudi::Units::mm;
37 TCL4JawDistB2I = 57*Gaudi::Units::mm;
38 TCL5JawDistB2I = 57*Gaudi::Units::mm;
39 TCL6JawDistB2I = 57*Gaudi::Units::mm;
40 TCL4JawDistB1O = 57*Gaudi::Units::mm;
41 TCL5JawDistB1O = 57*Gaudi::Units::mm;
42 TCL6JawDistB1O = 57*Gaudi::Units::mm;
43 TCL4JawDistB2O = 57*Gaudi::Units::mm;
44 TCL5JawDistB2O = 57*Gaudi::Units::mm;
45 TCL6JawDistB2O = 57*Gaudi::Units::mm;
46 vp1Compatibility = false;
47 buildTCL4 = false;
48 buildTCL6 = false;
49 ALFAInNewPosition = false;
50 newPosB7L1 = 245656.77*Gaudi::Units::mm;
51 newPosB7R1 = -245656.11*Gaudi::Units::mm;
52 posAFPL1 = 204500*Gaudi::Units::mm;
53 posAFPL2 = 212675*Gaudi::Units::mm;
54 posAFPR1 = -204500*Gaudi::Units::mm;
55 posAFPL2 = -212675*Gaudi::Units::mm;
56 posZDC1 = 141580*Gaudi::Units::mm;
57 posZDC2 = -141580*Gaudi::Units::mm;
58}
59
60
62 :m_detectorStore(detStore),
63 m_properties("ForwardRegionProperties")
64{
65 m_detectorManager = NULL;
66 MsgStream LogStream(Athena::getMessageSvc(), "ForwardRegionGeoModel::ForwardRegionGeoModel()");
67
68 m_Config = *pConfig;
69
70 if(m_properties.retrieve().isFailure()){
71 LogStream << MSG::ERROR << ": Failed to load magnet properties" << endmsg;
72 return;
73 }
74
75 m_MagConfig = *(m_properties->getConf());
76}
77
78
83
84
86{
87 std::string matName;
88
89 StoredMaterialManager* materialManager = nullptr;
90 if (StatusCode::SUCCESS != m_detectorStore->retrieve(materialManager, std::string("MATERIALS"))) {
91 return;
92 }
93
94
95 //-----------------------------------------------------------------------------------//
96 // Get the materials that we shall use. //
97 // ----------------------------------------------------------------------------------//
98
99 // vacuum
100 matName = "std::Vacuum";
101 const GeoMaterial *vacuum = materialManager->getMaterial(matName);
102 m_MapMaterials.emplace(matName,vacuum);
103
104 // water
105 matName = "water";
106 GeoMaterial *water = new GeoMaterial("H20", 1.0*GeoModelKernelUnits::gram/Gaudi::Units::cm3);
107 GeoElement *hydrogen = new GeoElement("Hydrogen","H",1.0, 1.010);
108 GeoElement *oxygen = new GeoElement("Oxygen", "O", 8.0, 16.0);
109 water->add(hydrogen,0.11);
110 water->add(oxygen,0.89);
111 water->lock();
112 m_MapMaterials.emplace(matName,water);
113
114 // elements
115 const GeoElement* C = materialManager->getElement("Carbon");
116 const GeoElement* N = materialManager->getElement("Nitrogen");
117 const GeoElement* Si = materialManager->getElement("Silicon");
118 const GeoElement* P = materialManager->getElement("Phosphorus");
119 const GeoElement* S = materialManager->getElement("Sulfur");
120 const GeoElement* Cr = materialManager->getElement("Chromium");
121 const GeoElement* Mn = materialManager->getElement("Manganese");
122 const GeoElement* Fe = materialManager->getElement("Iron");
123 const GeoElement* Ni = materialManager->getElement("Nickel");
124 const GeoElement* Mo = materialManager->getElement("Molybdenum");
125 const GeoElement* Cu = materialManager->getElement("Copper");
126
127
128 const GeoElement* Al = materialManager->getElement("Aluminium");
129 const GeoElement* B = materialManager->getElement("Boron");
130 const GeoElement* O = materialManager->getElement("Oxygen");
131
132 // Copper for beam screens
133 matName = "Copper";
134 GeoMaterial *copper = new GeoMaterial("Copper", 8.94*GeoModelKernelUnits::g/Gaudi::Units::cm3);
135 copper->add(const_cast<GeoElement*> (Cu),1.0);
136 copper->lock();
137 m_MapMaterials.insert(std::pair<std::string,GeoMaterial*>(matName,copper));
138
139 // Tungsten for TCL6
140 matName = "Tungsten";
141 const GeoElement* W = materialManager->getElement("Wolfram");
142 GeoMaterial *tungsten = new GeoMaterial("Tungsten", 19.25*GeoModelKernelUnits::g/Gaudi::Units::cm3);
143 tungsten->add(const_cast<GeoElement*> (W),1.0);
144 tungsten->lock();
145 m_MapMaterials.insert(std::pair<std::string,GeoMaterial*>(matName,tungsten));
146
147 // GlidCop AL15 copper -- aproximate composition (trace impurities (< 0.01 wt. %) not included)
148 // source: http://www-ferp.ucsd.edu/LIB/PROPS/compcu15.html
149 matName = "GlidCopAL15";
150 GeoMaterial *glidcop=new GeoMaterial("GlidCopAL15", 8.90*GeoModelKernelUnits::g/Gaudi::Units::cm3);
151
152 double aCu, aAl, aO, aB, aTot;
153
154 aCu=99.7*Cu->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
155 aAl=0.15*Al->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
156 aO=0.13*O->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
157 aB=0.02*B->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
158 aTot=aCu+aAl+aO+aB;
159
160 glidcop->add(const_cast<GeoElement*> (Cu), aCu/aTot);
161 glidcop->add(const_cast<GeoElement*> (Al), aAl/aTot);
162 glidcop->add(const_cast<GeoElement*> (O), aO/aTot);
163 glidcop->add(const_cast<GeoElement*> (B), aB/aTot);
164 glidcop->lock();
165 m_MapMaterials.insert(std::pair<std::string,GeoMaterial*>(matName,glidcop));
166
167 // Steel Grade 316L (Roman Pot)
168 matName = "Steel";
169 GeoMaterial *steel=new GeoMaterial("Steel", 8*GeoModelKernelUnits::g/Gaudi::Units::cm3);
170
171 double aC,aN,aSi,aP,aS,aCr,aMn,aFe,aNi,aMo,Atot;
172
173 aFe=62.045*Fe->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
174 aC =0.03*C ->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
175 aMn=2.0*Mn ->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
176 aSi=0.75*Si->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
177 aP =0.045*P->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
178 aS =0.03*S ->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
179 aCr=18.0*Cr->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
180 aMo=3.0*Mo ->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
181 aNi=14.0*Ni->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
182 aN =0.10*N ->getA()/(GeoModelKernelUnits::g/Gaudi::Units::mole);
183 Atot=aFe+aC+aMn+aSi+aP+aS+aCr+aMo+aNi+aN;
184
185 steel->add(const_cast<GeoElement*> (Fe),aFe/Atot);
186 steel->add(const_cast<GeoElement*> (C), aC/Atot);
187 steel->add(const_cast<GeoElement*> (Mn),aMn/Atot);
188 steel->add(const_cast<GeoElement*> (Si),aSi/Atot);
189 steel->add(const_cast<GeoElement*> (P), aP/Atot);
190 steel->add(const_cast<GeoElement*> (S), aS/Atot);
191 steel->add(const_cast<GeoElement*> (Cr),aCr/Atot);
192 steel->add(const_cast<GeoElement*> (Mo),aMo/Atot);
193 steel->add(const_cast<GeoElement*> (Ni),aNi/Atot);
194 steel->add(const_cast<GeoElement*> (N), aN/Atot);
195 steel->lock();
196 m_MapMaterials.insert(std::pair<std::string,GeoMaterial*>(matName,steel));
197}
198
199template <class T>
201{
202 std::ostringstream strs;
203 strs << num;
204 return strs.str();
205}
206
207template <typename T> int ForwardRegionGeoModelFactory::sgn(T val) {
208 return (T(0) < val) - (val < T(0));
209}
210
211void ForwardRegionGeoModelFactory::constructElements(GeoPhysVol *fwrPhys,std::vector<std::vector<std::string> > loadedDataFile, int beam)
212{
213 //-------------------------------------------------------------------------------------
214 // Construction of geometry from geometry file
215
216 // indexes
217 int name, zStart, zEnd, type, xAperture, yAperture, xStart, xEnd, yStart, yEnd, tubeThickness;
218 name = 0;
219 type = 1;
220 zStart = 4;
221 zEnd = 5;
222 xAperture = 2;
223 yAperture = 3;
224 xStart = 6;
225 xEnd = 7;
226 yStart = 8;
227 yEnd = 9;
228 tubeThickness = 10;
229
230 int lDFSize = loadedDataFile.size();
231
232 // apply shifts of magnets defined by magnets properties in JO
233 for(int i=0; i < lDFSize; i++)
234 {
235 // get start and end points defined in JO
236 HepGeom::Point3D<double> pointMagStart;
237 HepGeom::Point3D<double> pointMagEnd;
238 if(m_properties.retrieve().isSuccess()) m_properties->getMagTransforms(loadedDataFile[i][name],beam,pointMagStart,pointMagEnd);
239
240 // are points defined (non-zero)? If not, shifts will not apply
241 bool pointsDefined = !(pointMagStart.distance2() == 0 || pointMagEnd.distance2() == 0);
242
243 if(pointsDefined)
244 {
245
246 // overlap correction for x rotation
247 double startZ = pointMagStart[2];
248 double endZ = pointMagEnd[2];
249 double startX = pointMagStart[0];
250 double endX = pointMagEnd[0];
251 double rotationAngle = atan2(endX - startX,endZ - startZ);
252 double r = atof(loadedDataFile[i][xAperture].c_str())*Gaudi::Units::mm/2;
253 double dL = abs(r*tan(rotationAngle))+0.2*Gaudi::Units::mm;
254
255
256 // move start and end points of the magnet element and neighbour elemens accordingly
257 // move (resize) neighbours only in z (needed to avoid overlaps)
258 loadedDataFile[i][xStart] = num2str(pointMagStart[0]/1000);
259 loadedDataFile[i][yStart] = num2str(pointMagStart[1]/1000);
260 loadedDataFile[i][zStart] = num2str(pointMagStart[2]/1000);
261 if (not std::in_range<std::size_t>(i-1)){
262 throw std::runtime_error("ForwardRegionGeoModelFactory::constructElements: i-1 invalid conversion to std::size_t for index into vector.");
263 }
264 loadedDataFile[i-1][zEnd] = num2str(sgn(pointMagStart[2])*(abs(pointMagStart[2])-dL)/1000);
265
266 loadedDataFile[i][xEnd] = num2str(pointMagEnd[0]/1000);
267 loadedDataFile[i][yEnd] = num2str(pointMagEnd[1]/1000);
268 loadedDataFile[i+1][zStart] = num2str(sgn(pointMagEnd[2])*(abs(pointMagEnd[2])+dL)/1000);
269 loadedDataFile[i][zEnd] = num2str(pointMagEnd[2]/1000);
270
271 }
272 }
273
274 double x,y,z,halfL,rotationAngle,r,dL,startZ,endZ,startX,endX,startY,endY;
275
276 // ################ ELEMENTS ############################
277
278 // --------------- elements cycle -----------------
279 for(int i=0; i < lDFSize; i++)
280 {
281 startZ = atof(loadedDataFile[i][zStart].c_str())*Gaudi::Units::m;
282 endZ = atof(loadedDataFile[i][zEnd].c_str())*Gaudi::Units::m;
283 startX = atof(loadedDataFile[i][xStart].c_str())*Gaudi::Units::m;
284 endX = atof(loadedDataFile[i][xEnd].c_str())*Gaudi::Units::m;
285 startY = atof(loadedDataFile[i][yStart].c_str())*Gaudi::Units::m;
286 endY = atof(loadedDataFile[i][yEnd].c_str())*Gaudi::Units::m;
287
288 // translation of element
289 x = (startX + endX)/2;
290 y = (startY + endY)/2;
291 z = (startZ + endZ)/2;
292
293 // absolute rotation of element
294 //rotationAngle_old = rotationAngle;
295 rotationAngle = atan2(endX - startX,endZ - startZ);
296
297 // half-length of element
298 halfL = sqrt((endX - startX)*(endX - startX) + (endZ - startZ)*(endZ - startZ))/2;
299
300 r = atof(loadedDataFile[i][xAperture].c_str())*Gaudi::Units::mm/2;
301
302 // overlap correction
303 dL = abs(r*tan(rotationAngle))+0.2*Gaudi::Units::mm;
304
305 // do not shorten magnetic volumes
306 if(loadedDataFile[i][name].find("Mag") != std::string::npos)
307 dL = 0;
308
309 // construction of element
310
311 // circular aperture
312 if(atoi(loadedDataFile[i][type].c_str()) == 0){
313 // envelope to allow tracking with G4TrackAction
314 if(loadedDataFile[i][name] == "VCDBP.7R1.B"){
315 GeoPhysVol* trackEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, 100*Gaudi::Units::mm, halfL, dL, fwrPhys);
316 insertCircularElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), trackEnv);
317 }
318 else
319 insertCircularElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), fwrPhys);
320 }
321
322 // special volumes
323 if(atoi(loadedDataFile[i][type].c_str()) == 4){
324 if(loadedDataFile[i][name] == "VCTYF.A4R1.X") // Trousers -- transition from 1 to 2 beampipes
325 insertTrousersElement(loadedDataFile[i][name], x, y, z, rotationAngle, fwrPhys);
326 else if(loadedDataFile[i][name] == "TCL.5R1.B1") // TCL5 collimator
327 insertTCLElement(loadedDataFile[i][name], x, y, z, fwrPhys, (beam == 1 ? m_Config.TCL5JawDistB1O : m_Config.TCL5JawDistB2O), (beam == 1 ? m_Config.TCL5JawDistB1I : m_Config.TCL5JawDistB2I));
328 else if(m_Config.buildTCL4 && loadedDataFile[i][name] == "VCDSS.4R1.B") // TCL4 collimator
329 insertTCLElement(loadedDataFile[i][name], x, y, z, fwrPhys, (beam == 1 ? m_Config.TCL4JawDistB1O : m_Config.TCL4JawDistB2O), (beam == 1 ? m_Config.TCL4JawDistB1I : m_Config.TCL4JawDistB2I));
330 else if(m_Config.buildTCL6 && loadedDataFile[i][name] == "TCL6") // TCL6 collimator
331 insertTCLElement(loadedDataFile[i][name], x, y, z, fwrPhys, (beam == 1 ? m_Config.TCL6JawDistB1O : m_Config.TCL6JawDistB2O), (beam == 1 ? m_Config.TCL6JawDistB1I : m_Config.TCL6JawDistB2I), true);
332
333 // aproximate rest by circular apperture
334 else
335 insertCircularElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), fwrPhys);
336 }
337
338 GeoPhysVol* magEnv;
339
340 // elliptical aperture
341 if(atoi(loadedDataFile[i][type].c_str()) == 1) {
342 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, 20*Gaudi::Units::cm, halfL, dL, fwrPhys);
343 insertEllipticalElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), magEnv);
344 }
345
346
347 double magDiam = 19.4*Gaudi::Units::cm;
348 if(loadedDataFile[i][name].find("Mag") != std::string::npos)
349 magDiam= 19.4*Gaudi::Units::cm;
350 if(loadedDataFile[i][name] == "LQXAA.1R1MagQ1" || loadedDataFile[i][name] == "LQXAG.3R1MagQ3")
351 magDiam = 48*Gaudi::Units::cm;
352 if(loadedDataFile[i][name] == "LQXBA.2R1MagQ2a" || loadedDataFile[i][name] == "LQXBA.2R1MagQ2b")
353 magDiam = 52*Gaudi::Units::cm;
354 //else magDiam = std::max(atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()))+2*atof(loadedDataFile[i][tubeThickness].c_str());
355 //else magDiam = 19.4*Gaudi::Units::cm;
356
357 // rectcircular aperture with flats in x
358 if(atoi(loadedDataFile[i][type].c_str()) == 2) {
359 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, magDiam, halfL, dL, fwrPhys);
360 insertXRecticircularElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), magEnv);
361 }
362
363 // rectcircular aperture with flats in y
364 if(atoi(loadedDataFile[i][type].c_str()) == 3) {
365 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, magDiam, halfL, dL, fwrPhys);
366 insertYRecticircularElement(loadedDataFile[i][name], x, y, z, rotationAngle, atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()), halfL, dL, atof(loadedDataFile[i][tubeThickness].c_str()), magEnv);
367 }
368 }
369 // ################ ELEMENTS - end ########################
370}
371
372
374{
376
377 MsgStream LogStream(Athena::getMessageSvc(), "ForwardRegionGeoModel::create()");
378
379 LogStream << MSG::INFO << "Constructing forward region model" << endmsg;
380
382
383 // Load "geometry" files
384 std::vector<std::vector<std::string> > loadedDataFileR = this->loadDataFile("ForwardRegionGeoModel/LSS1Rout.csv",11);
385 std::vector<std::vector<std::string> > loadedDataFileL = this->loadDataFile("ForwardRegionGeoModel/LSS1Lout.csv",11);
386
387 double startZ,endZ;
388
389 if(m_Config.vp1Compatibility) startZ = 19.0*Gaudi::Units::m;
390 else startZ = 22.0*Gaudi::Units::m;
391 endZ = 268.904*Gaudi::Units::m;
392
393 //rotationAngle_old = 0;
394
395 // mother volume -- union of tubes, one for each side
396 //const GeoBox *fwrBox = new GeoBox(2*Gaudi::Units::m,0.5*Gaudi::Units::m,(endZ-startZ)/2);
397 const GeoTube *fwrTubeL = new GeoTube(0,2*Gaudi::Units::m,(endZ-startZ)/2);
398 GeoTube *fwrTubeR = new GeoTube(0,2*Gaudi::Units::m,(endZ-startZ)/2);
399 GeoTrf::Transform3D shiftL = GeoTrf::Translate3D(0,0,(endZ+startZ)/2);
400 GeoTrf::Transform3D shiftR = GeoTrf::Translate3D(0,0,-(endZ+startZ)/2);
401
402 const GeoShapeShift& fwrTube0 = (*fwrTubeL)<<shiftL;
403 const GeoShapeUnion& fwrTube1 = fwrTube0.add((*fwrTubeR)<<shiftR);
404
405 // cut out slots for ALFA
406 const GeoTube *alfa = new GeoTube(0, 2*Gaudi::Units::m, 500*Gaudi::Units::mm);
407 GeoTrf::Transform3D shiftAlfaL1 = GeoTrf::Translate3D(0,0,237388*Gaudi::Units::mm);
408 GeoTrf::Transform3D shiftAlfaR1 = GeoTrf::Translate3D(0,0,-237408*Gaudi::Units::mm);
409 GeoTrf::Transform3D shiftAlfaL2 = GeoTrf::Translate3D(0,0,(m_Config.ALFAInNewPosition ? m_Config.newPosB7L1 : 241528*Gaudi::Units::mm));
410 GeoTrf::Transform3D shiftAlfaR2 = GeoTrf::Translate3D(0,0,(m_Config.ALFAInNewPosition ? m_Config.newPosB7R1 :-241548*Gaudi::Units::mm));
411 const GeoShapeSubtraction& fwrTube2 = fwrTube1.subtract((*alfa)<<shiftAlfaL1).subtract((*alfa)<<shiftAlfaL2).subtract((*alfa)<<shiftAlfaR1).subtract((*alfa)<<shiftAlfaR2);
412
413 // cut out slots for AFP
414 const GeoTube *afp = new GeoTube(0, 2.5*Gaudi::Units::m, 280*Gaudi::Units::mm);
415 const GeoTube *afp2 = new GeoTube(0, 2.5*Gaudi::Units::m, 580*Gaudi::Units::mm);
416 GeoTrf::Transform3D shiftAfpL1 = GeoTrf::Translate3D(0,0,m_Config.posAFPL1);
417 GeoTrf::Transform3D shiftAfpR1 = GeoTrf::Translate3D(0,0,m_Config.posAFPR1);
418 GeoTrf::Transform3D shiftAfpL2 = GeoTrf::Translate3D(0,0,m_Config.posAFPL2);
419 GeoTrf::Transform3D shiftAfpR2 = GeoTrf::Translate3D(0,0,m_Config.posAFPR2);
420 const GeoShapeSubtraction& fwrTube3 = fwrTube2.subtract((*afp)<<shiftAfpL1).subtract((*afp)<<shiftAfpR1).subtract((*afp2)<<shiftAfpL2).subtract((*afp2)<<shiftAfpR2);
421
422 // cut out slots for ZDC
423 const GeoBox *zdc = new GeoBox( 9.1*Gaudi::Units::cm/2.0 ,18.1*Gaudi::Units::cm/2.0 , 94.4*Gaudi::Units::cm/2.0);
424 GeoTrf::Transform3D shiftZdcL1 = GeoTrf::Translate3D(0,0, m_Config.posZDC1);
425 GeoTrf::Transform3D shiftZdcR1 = GeoTrf::Translate3D(0,0, m_Config.posZDC2);
426 const GeoShapeSubtraction& fwrTube = fwrTube3.subtract((*zdc)<<shiftZdcL1).subtract((*zdc)<<shiftZdcR1);
427
428
429 const GeoLogVol *fwrLog = new GeoLogVol("ForwardRegionGeoModel", &fwrTube, m_MapMaterials[std::string("std::Vacuum")]);
430 GeoPhysVol *fwrPhys = new GeoPhysVol(fwrLog);
431 GeoNameTag *tag = new GeoNameTag("ForwardRegionGeoModel");
432 world->add(tag);
433 world->add(fwrPhys);
434 m_detectorManager->addTreeTop(fwrPhys);
435
436 constructElements(fwrPhys,std::move(loadedDataFileR),1);
437 constructElements(fwrPhys,std::move(loadedDataFileL),2);
438
439 LogStream << MSG::INFO << "Forward region model succesfully constructed." << endmsg;
440}
441
446
447// Load data from file into 2D array of strings. Input is filename and wanted numbestd::stringof columns
448std::vector<std::vector<std::string> > ForwardRegionGeoModelFactory::loadDataFile(const std::string& fileName, int cols)
449{
450 std::vector<std::vector<std::string> > loadedData;
451
452 MsgStream LogStream(Athena::getMessageSvc(), "ForwardRegionGeoModel::loadDataFile()");
453
454 std::ifstream file (fileName);
455 if(!file){
456 std::string datapath = PathResolverFindDataFile(fileName);
457 LogStream << MSG::DEBUG << "File " << fileName << " not found in run directory, trying to load it from DATAPATH" << endmsg;
458 file.open(datapath.c_str());
459 }
460
461 if(!file)
462 LogStream << MSG::FATAL << "Unable to load " << fileName << endmsg;
463
464 if(file.is_open())
465 {
466 std::vector<std::string> row (cols);
467 char c;
468
469 while(file.get(c))
470 {
471 if(c != '@' && c != '#' && c != '*' && c != '$' && c != '%')
472 {
473 file.unget();
474 for(int i = 0; i<cols; i++) // load desired columns
475 {
476 file >> row[i];
477 }
478 loadedData.push_back(row); //store them
479 file.ignore(1024,'\n'); // discard rest of line
480 }
481 else
482 file.ignore(1024, '\n'); // discard commented lines
483 }
484 LogStream << MSG::INFO << "File " << fileName << " succesfully loaded." << endmsg;
485 file.close();
486 }
487 return loadedData;
488}
#define endmsg
struct _FWD_CONFIGURATION * PFWD_CONFIGURATION
static Double_t P(Double_t *tt, Double_t *par)
std::string PathResolverFindDataFile(const std::string &logical_file_name)
#define y
#define x
#define z
void insertTrousersElement(const std::string &name, double x, double y, double z, double rotationAngle, GeoPhysVol *fwrPhys)
ToolHandle< IForwardRegionProperties > m_properties
GeoPhysVol * insertMagnetEnvelope(const std::string &name, double x, double y, double z, double rotationAngle, double diameter, double halfL, double dL, GeoPhysVol *fwrPhys)
void insertEllipticalElement(const std::string &name, double x, double y, double z, double rotationAngle, double xAperture, double yAperture, double halfL, double dL, double tubeThickness, GeoPhysVol *fwrPhys)
void insertYRecticircularElement(const std::string &name, double x, double y, double z, double rotationAngle, double xAperture, double yAperture, double halfL, double dL, double tubeThickness, GeoPhysVol *fwrPhys)
void constructElements(GeoPhysVol *fwrPhys, std::vector< std::vector< std::string > > loadedDataFile, int beam)
void insertTCLElement(const std::string &name, double x, double y, double z, GeoPhysVol *fwrPhys, double TCLJawDistO, double TCLJawDistI, bool tungstenInsteadOfCopper=false)
void insertCircularElement(const std::string &name, double x, double y, double z, double rotationAngle, double xAperture, double yAperture, double halfL, double dL, double tubeThickness, GeoPhysVol *fwrPhys)
std::map< std::string, const GeoMaterial * > m_MapMaterials
virtual void create(GeoPhysVol *world)
virtual const ForwardRegionGeoModelManager * getDetectorManager() const
std::vector< std::vector< std::string > > loadDataFile(const std::string &fileName, int cols)
void insertXRecticircularElement(const std::string &name, double x, double y, double z, double rotationAngle, double xAperture, double yAperture, double halfL, double dL, double tubeThickness, GeoPhysVol *fwrPhys)
ForwardRegionGeoModelManager * m_detectorManager
ForwardRegionGeoModelFactory(StoreGateSvc *pDetStore, const PFWD_CONFIGURATION pConfig)
The Athena Transient Store API.
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(std::string_view name)=0
virtual const GeoElement * getElement(const std::string &name)=0
int r
Definition globals.cxx:22
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
struct color C
IMessageSvc * getMessageSvc(bool quiet=false)
TFile * file