ATLAS Offline Software
Loading...
Searching...
No Matches
ForwardRegionGeoModelFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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 loadedDataFile[i-1][zEnd] = num2str(sgn(pointMagStart[2])*(abs(pointMagStart[2])-dL)/1000);
262
263 loadedDataFile[i][xEnd] = num2str(pointMagEnd[0]/1000);
264 loadedDataFile[i][yEnd] = num2str(pointMagEnd[1]/1000);
265 loadedDataFile[i+1][zStart] = num2str(sgn(pointMagEnd[2])*(abs(pointMagEnd[2])+dL)/1000);
266 loadedDataFile[i][zEnd] = num2str(pointMagEnd[2]/1000);
267
268 }
269 }
270
271 double x,y,z,halfL,rotationAngle,r,dL,startZ,endZ,startX,endX,startY,endY;
272
273 // ################ ELEMENTS ############################
274
275 // --------------- elements cycle -----------------
276 for(int i=0; i < lDFSize; i++)
277 {
278 startZ = atof(loadedDataFile[i][zStart].c_str())*Gaudi::Units::m;
279 endZ = atof(loadedDataFile[i][zEnd].c_str())*Gaudi::Units::m;
280 startX = atof(loadedDataFile[i][xStart].c_str())*Gaudi::Units::m;
281 endX = atof(loadedDataFile[i][xEnd].c_str())*Gaudi::Units::m;
282 startY = atof(loadedDataFile[i][yStart].c_str())*Gaudi::Units::m;
283 endY = atof(loadedDataFile[i][yEnd].c_str())*Gaudi::Units::m;
284
285 // translation of element
286 x = (startX + endX)/2;
287 y = (startY + endY)/2;
288 z = (startZ + endZ)/2;
289
290 // absolute rotation of element
291 //rotationAngle_old = rotationAngle;
292 rotationAngle = atan2(endX - startX,endZ - startZ);
293
294 // half-length of element
295 halfL = sqrt((endX - startX)*(endX - startX) + (endZ - startZ)*(endZ - startZ))/2;
296
297 r = atof(loadedDataFile[i][xAperture].c_str())*Gaudi::Units::mm/2;
298
299 // overlap correction
300 dL = abs(r*tan(rotationAngle))+0.2*Gaudi::Units::mm;
301
302 // do not shorten magnetic volumes
303 if(loadedDataFile[i][name].find("Mag") != std::string::npos)
304 dL = 0;
305
306 // construction of element
307
308 // circular aperture
309 if(atoi(loadedDataFile[i][type].c_str()) == 0){
310 // envelope to allow tracking with G4TrackAction
311 if(loadedDataFile[i][name] == "VCDBP.7R1.B"){
312 GeoPhysVol* trackEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, 100*Gaudi::Units::mm, halfL, dL, fwrPhys);
313 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);
314 }
315 else
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()), fwrPhys);
317 }
318
319 // special volumes
320 if(atoi(loadedDataFile[i][type].c_str()) == 4){
321 if(loadedDataFile[i][name] == "VCTYF.A4R1.X") // Trousers -- transition from 1 to 2 beampipes
322 insertTrousersElement(loadedDataFile[i][name], x, y, z, rotationAngle, fwrPhys);
323 else if(loadedDataFile[i][name] == "TCL.5R1.B1") // TCL5 collimator
324 insertTCLElement(loadedDataFile[i][name], x, y, z, fwrPhys, (beam == 1 ? m_Config.TCL5JawDistB1O : m_Config.TCL5JawDistB2O), (beam == 1 ? m_Config.TCL5JawDistB1I : m_Config.TCL5JawDistB2I));
325 else if(m_Config.buildTCL4 && loadedDataFile[i][name] == "VCDSS.4R1.B") // TCL4 collimator
326 insertTCLElement(loadedDataFile[i][name], x, y, z, fwrPhys, (beam == 1 ? m_Config.TCL4JawDistB1O : m_Config.TCL4JawDistB2O), (beam == 1 ? m_Config.TCL4JawDistB1I : m_Config.TCL4JawDistB2I));
327 else if(m_Config.buildTCL6 && loadedDataFile[i][name] == "TCL6") // TCL6 collimator
328 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);
329
330 // aproximate rest by circular apperture
331 else
332 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);
333 }
334
335 GeoPhysVol* magEnv;
336
337 // elliptical aperture
338 if(atoi(loadedDataFile[i][type].c_str()) == 1) {
339 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, 20*Gaudi::Units::cm, halfL, dL, fwrPhys);
340 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);
341 }
342
343
344 double magDiam = 19.4*Gaudi::Units::cm;
345 if(loadedDataFile[i][name].find("Mag") != std::string::npos)
346 magDiam= 19.4*Gaudi::Units::cm;
347 if(loadedDataFile[i][name] == "LQXAA.1R1MagQ1" || loadedDataFile[i][name] == "LQXAG.3R1MagQ3")
348 magDiam = 48*Gaudi::Units::cm;
349 if(loadedDataFile[i][name] == "LQXBA.2R1MagQ2a" || loadedDataFile[i][name] == "LQXBA.2R1MagQ2b")
350 magDiam = 52*Gaudi::Units::cm;
351 //else magDiam = std::max(atof(loadedDataFile[i][xAperture].c_str()), atof(loadedDataFile[i][yAperture].c_str()))+2*atof(loadedDataFile[i][tubeThickness].c_str());
352 //else magDiam = 19.4*Gaudi::Units::cm;
353
354 // rectcircular aperture with flats in x
355 if(atoi(loadedDataFile[i][type].c_str()) == 2) {
356 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, magDiam, halfL, dL, fwrPhys);
357 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);
358 }
359
360 // rectcircular aperture with flats in y
361 if(atoi(loadedDataFile[i][type].c_str()) == 3) {
362 magEnv = insertMagnetEnvelope(loadedDataFile[i][name], x, y, z, rotationAngle, magDiam, halfL, dL, fwrPhys);
363 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);
364 }
365 }
366 // ################ ELEMENTS - end ########################
367}
368
369
371{
373
374 MsgStream LogStream(Athena::getMessageSvc(), "ForwardRegionGeoModel::create()");
375
376 LogStream << MSG::INFO << "Constructing forward region model" << endmsg;
377
379
380 // Load "geometry" files
381 std::vector<std::vector<std::string> > loadedDataFileR = this->loadDataFile("ForwardRegionGeoModel/LSS1Rout.csv",11);
382 std::vector<std::vector<std::string> > loadedDataFileL = this->loadDataFile("ForwardRegionGeoModel/LSS1Lout.csv",11);
383
384 double startZ,endZ;
385
386 if(m_Config.vp1Compatibility) startZ = 19.0*Gaudi::Units::m;
387 else startZ = 22.0*Gaudi::Units::m;
388 endZ = 268.904*Gaudi::Units::m;
389
390 //rotationAngle_old = 0;
391
392 // mother volume -- union of tubes, one for each side
393 //const GeoBox *fwrBox = new GeoBox(2*Gaudi::Units::m,0.5*Gaudi::Units::m,(endZ-startZ)/2);
394 const GeoTube *fwrTubeL = new GeoTube(0,2*Gaudi::Units::m,(endZ-startZ)/2);
395 GeoTube *fwrTubeR = new GeoTube(0,2*Gaudi::Units::m,(endZ-startZ)/2);
396 GeoTrf::Transform3D shiftL = GeoTrf::Translate3D(0,0,(endZ+startZ)/2);
397 GeoTrf::Transform3D shiftR = GeoTrf::Translate3D(0,0,-(endZ+startZ)/2);
398
399 const GeoShapeShift& fwrTube0 = (*fwrTubeL)<<shiftL;
400 const GeoShapeUnion& fwrTube1 = fwrTube0.add((*fwrTubeR)<<shiftR);
401
402 // cut out slots for ALFA
403 const GeoTube *alfa = new GeoTube(0, 2*Gaudi::Units::m, 500*Gaudi::Units::mm);
404 GeoTrf::Transform3D shiftAlfaL1 = GeoTrf::Translate3D(0,0,237388*Gaudi::Units::mm);
405 GeoTrf::Transform3D shiftAlfaR1 = GeoTrf::Translate3D(0,0,-237408*Gaudi::Units::mm);
406 GeoTrf::Transform3D shiftAlfaL2 = GeoTrf::Translate3D(0,0,(m_Config.ALFAInNewPosition ? m_Config.newPosB7L1 : 241528*Gaudi::Units::mm));
407 GeoTrf::Transform3D shiftAlfaR2 = GeoTrf::Translate3D(0,0,(m_Config.ALFAInNewPosition ? m_Config.newPosB7R1 :-241548*Gaudi::Units::mm));
408 const GeoShapeSubtraction& fwrTube2 = fwrTube1.subtract((*alfa)<<shiftAlfaL1).subtract((*alfa)<<shiftAlfaL2).subtract((*alfa)<<shiftAlfaR1).subtract((*alfa)<<shiftAlfaR2);
409
410 // cut out slots for AFP
411 const GeoTube *afp = new GeoTube(0, 2.5*Gaudi::Units::m, 280*Gaudi::Units::mm);
412 const GeoTube *afp2 = new GeoTube(0, 2.5*Gaudi::Units::m, 580*Gaudi::Units::mm);
413 GeoTrf::Transform3D shiftAfpL1 = GeoTrf::Translate3D(0,0,m_Config.posAFPL1);
414 GeoTrf::Transform3D shiftAfpR1 = GeoTrf::Translate3D(0,0,m_Config.posAFPR1);
415 GeoTrf::Transform3D shiftAfpL2 = GeoTrf::Translate3D(0,0,m_Config.posAFPL2);
416 GeoTrf::Transform3D shiftAfpR2 = GeoTrf::Translate3D(0,0,m_Config.posAFPR2);
417 const GeoShapeSubtraction& fwrTube3 = fwrTube2.subtract((*afp)<<shiftAfpL1).subtract((*afp)<<shiftAfpR1).subtract((*afp2)<<shiftAfpL2).subtract((*afp2)<<shiftAfpR2);
418
419 // cut out slots for ZDC
420 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);
421 GeoTrf::Transform3D shiftZdcL1 = GeoTrf::Translate3D(0,0, m_Config.posZDC1);
422 GeoTrf::Transform3D shiftZdcR1 = GeoTrf::Translate3D(0,0, m_Config.posZDC2);
423 const GeoShapeSubtraction& fwrTube = fwrTube3.subtract((*zdc)<<shiftZdcL1).subtract((*zdc)<<shiftZdcR1);
424
425
426 const GeoLogVol *fwrLog = new GeoLogVol("ForwardRegionGeoModel", &fwrTube, m_MapMaterials[std::string("std::Vacuum")]);
427 GeoPhysVol *fwrPhys = new GeoPhysVol(fwrLog);
428 GeoNameTag *tag = new GeoNameTag("ForwardRegionGeoModel");
429 world->add(tag);
430 world->add(fwrPhys);
431 m_detectorManager->addTreeTop(fwrPhys);
432
433 constructElements(fwrPhys,std::move(loadedDataFileR),1);
434 constructElements(fwrPhys,std::move(loadedDataFileL),2);
435
436 LogStream << MSG::INFO << "Forward region model succesfully constructed." << endmsg;
437}
438
443
444// Load data from file into 2D array of strings. Input is filename and wanted numbestd::stringof columns
445std::vector<std::vector<std::string> > ForwardRegionGeoModelFactory::loadDataFile(const std::string& fileName, int cols)
446{
447 std::vector<std::vector<std::string> > loadedData;
448
449 MsgStream LogStream(Athena::getMessageSvc(), "ForwardRegionGeoModel::loadDataFile()");
450
451 std::ifstream file (fileName);
452 if(!file){
453 std::string datapath = PathResolverFindDataFile(fileName);
454 LogStream << MSG::DEBUG << "File " << fileName << " not found in run directory, trying to load it from DATAPATH" << endmsg;
455 file.open(datapath.c_str());
456 }
457
458 if(!file)
459 LogStream << MSG::FATAL << "Unable to load " << fileName << endmsg;
460
461 if(file.is_open())
462 {
463 std::vector<std::string> row (cols);
464 char c;
465
466 while(file.get(c))
467 {
468 if(c != '@' && c != '#' && c != '*' && c != '$' && c != '%')
469 {
470 file.unget();
471 for(int i = 0; i<cols; i++) // load desired columns
472 {
473 file >> row[i];
474 }
475 loadedData.push_back(row); //store them
476 file.ignore(1024,'\n'); // discard rest of line
477 }
478 else
479 file.ignore(1024, '\n'); // discard commented lines
480 }
481 LogStream << MSG::INFO << "File " << fileName << " succesfully loaded." << endmsg;
482 file.close();
483 }
484 return loadedData;
485}
#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 GeoElement * getElement(const std::string &name)=0
virtual const GeoMaterial * getMaterial(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:138
struct color C
IMessageSvc * getMessageSvc(bool quiet=false)
TFile * file