ATLAS Offline Software
Loading...
Searching...
No Matches
AFP_GeoModelFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include "GeoModelKernel/GeoMaterial.h"
9#include "GeoModelKernel/GeoBox.h"
10#include "GeoModelKernel/GeoLogVol.h"
11#include "GeoModelKernel/GeoNameTag.h"
12#include "GeoModelKernel/GeoPhysVol.h"
13#include "GeoModelKernel/GeoFullPhysVol.h"
14#include "GeoModelKernel/GeoTransform.h"
15#include "GeoModelKernel/GeoAlignableTransform.h"
16
17#include "CLHEP/GenericFunctions/AbsFunction.hh"
18#include "CLHEP/GenericFunctions/Variable.hh"
19#include "CLHEP/GenericFunctions/Sin.hh"
20#include "CLHEP/GenericFunctions/Cos.hh"
22
23
31
33
34#include <cstdio>
35
36
37using namespace Genfun;
38using namespace CLHEP;
39
41 :m_pDetectorStore(detStore)
42{
43 pGeometry->getCfgParams(&m_CfgParams);
44 m_pGeometry=pGeometry;
45
47}
48
49
54
56{
57 int i;
58 const double fWl2E=1239.85; //nm<->eV
59 std::string matName;
60 GeoMaterialPropertiesTable *pMPT=nullptr;
61
62 StoredMaterialManager * materialManager = nullptr;
63 if (StatusCode::SUCCESS != m_pDetectorStore->retrieve(materialManager, std::string("MATERIALS")))
64 {
65 return;
66 }
67
68 double aH,aC,aN,aSi,aP,aS,aCr,aMn,aFe,aNi,aMo,aAl,aO,Atot;
69 const GeoElement* H = materialManager->getElement("Hydrogen");
70 const GeoElement* C = materialManager->getElement("Carbon");
71 const GeoElement* N = materialManager->getElement("Nitrogen");
72 const GeoElement* Si = materialManager->getElement("Silicon");
73 const GeoElement* P = materialManager->getElement("Phosphorus");
74 const GeoElement* S = materialManager->getElement("Sulfur");
75 const GeoElement* Cr = materialManager->getElement("Chromium");
76 const GeoElement* Mn = materialManager->getElement("Manganese");
77 const GeoElement* Fe = materialManager->getElement("Iron");
78 const GeoElement* Ni = materialManager->getElement("Nickel");
79 const GeoElement* Mo = materialManager->getElement("Molybdenum");
80 const GeoElement* Al = materialManager->getElement("Aluminium");
81 const GeoElement* O = materialManager->getElement("Oxygen");
82 const GeoElement* Be = materialManager->getElement("Beryllium");
83
84 // vacuum
85 matName = "std::Vacuum";
86 const GeoMaterial *vacuum = materialManager->getMaterial(matName);
87 m_MapMaterials.emplace(matName,vacuum);
88
89 // optical vacuum
90 matName = "OpticalVacuum";
91 GeoExtendedMaterial* pMatOptVacuum=new GeoExtendedMaterial(matName, (1E-24)*CLHEP::g/CLHEP::cm3);
92 pMatOptVacuum->add(const_cast<GeoElement*> (H), 1);
93 double PhotonEnergyOptVac[2] = {0.44*CLHEP::eV, 6.3*CLHEP::eV};
94 double RefractiveIndexOptVac[2] = {1.0, 1.0};
95 double AbsorptionOptVac[2] ={1E-5*CLHEP::m, 1E-5*CLHEP::m};
96
98 pMPT->AddProperty("RINDEX", PhotonEnergyOptVac, RefractiveIndexOptVac , 2);
99 pMPT->AddProperty("ABSLENGTH", PhotonEnergyOptVac, AbsorptionOptVac, 2);
100 pMatOptVacuum->SetMaterialPropertiesTable(pMPT);
101 pMatOptVacuum->lock();
102 m_MapMaterials.emplace(matName,pMatOptVacuum);
103
104 // Steel Grade 316L (Roman Pot)
105 matName="Steel_AFP";
106 GeoMaterial *steel=new GeoMaterial(matName, 8*g/cm3);
107
108 aFe=62.045*Fe->getA()/(CLHEP::g/CLHEP::mole);
109 aC =0.03*C ->getA()/(CLHEP::g/CLHEP::mole);
110 aMn=2.0*Mn ->getA()/(CLHEP::g/CLHEP::mole);
111 aSi=0.75*Si->getA()/(CLHEP::g/CLHEP::mole);
112 aP =0.045*P->getA()/(CLHEP::g/CLHEP::mole);
113 aS =0.03*S ->getA()/(CLHEP::g/CLHEP::mole);
114 aCr=18.0*Cr->getA()/(CLHEP::g/CLHEP::mole);
115 aMo=3.0*Mo ->getA()/(CLHEP::g/CLHEP::mole);
116 aNi=14.0*Ni->getA()/(CLHEP::g/CLHEP::mole);
117 aN =0.10*N ->getA()/(CLHEP::g/CLHEP::mole);
118 Atot=aFe+aC+aMn+aSi+aP+aS+aCr+aMo+aNi+aN;
119
120 steel->add(const_cast<GeoElement*> (Fe),aFe/Atot);
121 steel->add(const_cast<GeoElement*> (C), aC/Atot);
122 steel->add(const_cast<GeoElement*> (Mn),aMn/Atot);
123 steel->add(const_cast<GeoElement*> (Si),aSi/Atot);
124 steel->add(const_cast<GeoElement*> (P), aP/Atot);
125 steel->add(const_cast<GeoElement*> (S), aS/Atot);
126 steel->add(const_cast<GeoElement*> (Cr),aCr/Atot);
127 steel->add(const_cast<GeoElement*> (Mo),aMo/Atot);
128 steel->add(const_cast<GeoElement*> (Ni),aNi/Atot);
129 steel->add(const_cast<GeoElement*> (N), aN/Atot);
130 steel->lock();
131 m_MapMaterials.emplace(matName,steel);
132
133 // CE7 70% Si, 30% Al
134 matName="CE7";
135 GeoMaterial *pMatCE7=new GeoMaterial(matName, 2.4*g/cm3);
136 aSi=0.70*Si->getA()/(g/mole);
137 aAl=0.30*Al->getA()/(g/mole);
138 Atot=aSi+aAl;
139 pMatCE7->add(const_cast<GeoElement*> (Si),aSi/Atot);
140 pMatCE7->add(const_cast<GeoElement*> (Al),aAl/Atot);
141 pMatCE7->lock();
142 m_MapMaterials.emplace(matName,pMatCE7);
143
144 // Quartz 70% SiO2 for TD Quartic (with refractive index and absorption length)
145 matName="Quartz";
146 GeoExtendedMaterial *pMatQuartz=new GeoExtendedMaterial(matName, 2.6*g/cm3, stateSolid, CLHEP::STP_Temperature);
147 aSi=1.0*Si->getA()/(g/mole);
148 aO=2.0*O->getA()/(g/mole);
149 Atot=aSi+aO;
150 pMatQuartz->add(const_cast<GeoElement*> (Si),aSi/Atot);
151 pMatQuartz->add(const_cast<GeoElement*> (O),aO/Atot);
152
153 // Defining the refractive index of quartz
154 const int nEntriesCnt1=12; // (M.G.Albrow, JINST 2012) + extrapolation to 200.0 nm
155 double arrEnergy1[nEntriesCnt1] = { 750.0*nm, 700.0*nm, 650.0*nm, 600.0*nm, 550.0*nm, 500.0*nm, 450.0*nm, 400.0*nm, 350.0*nm, 300.0*nm, 250.0*nm, 200.0*nm };
156 double arrQuartzRefIndex[nEntriesCnt1] = { 1.450, 1.455, 1.456, 1.458, 1.460, 1.462, 1.465, 1.470, 1.475, 1.488, 1.510, 1.541 };
157 double arrQuartzAbsLength[nEntriesCnt1] = { 130.0*cm, 130.0*cm, 130.0*cm, 130.0*cm, 128.0*cm, 125.0*cm, 122.0*cm, 120.0*cm, 111.0*cm, 104.0*cm, 95.0*cm, 83.3*cm };
158 for(i=0;i<nEntriesCnt1;i++) arrEnergy1[i]=(fWl2E/(arrEnergy1[i]/nm))*eV;
159
160 pMPT= new GeoMaterialPropertiesTable();
161 pMPT->AddProperty("RINDEX", arrEnergy1, arrQuartzRefIndex, nEntriesCnt1);
162 pMPT->AddProperty("ABSLENGTH", arrEnergy1, arrQuartzAbsLength, nEntriesCnt1);
163 pMatQuartz->SetMaterialPropertiesTable(pMPT);
164 pMatQuartz->lock();
165 m_MapMaterials.emplace(matName,pMatQuartz);
166
167 // Silicon for TD SiPMT (with refractive index)
168 matName="SiliconPMT";
169 GeoExtendedMaterial *pMatSiliconPMT=new GeoExtendedMaterial(matName, 2.3290*g/cm3, stateSolid, CLHEP::STP_Temperature);
170 aSi=1.0*Si->getA()/(g/mole);
171 pMatSiliconPMT->add(const_cast<GeoElement*> (Si),1.0);
172
173 const int nEntriesCnt2=2;
174 double arrEnergy2[nEntriesCnt2] = { 2800.0*nm, 190.0*nm };
175 double arrSiliconRefIndex[nEntriesCnt2] = { 4.0, 4.0 };
176 double arrSiliconAbsLength[nEntriesCnt2] = { 0.00001*m, 0.00001*m };
177 for(i=0;i<nEntriesCnt2;i++) arrEnergy2[i]=(fWl2E/(arrEnergy2[i]/nm))*eV;
178
179 pMPT = new GeoMaterialPropertiesTable();
180 pMPT->AddProperty("RINDEX", arrEnergy2, arrSiliconRefIndex, nEntriesCnt2);
181 pMPT->AddProperty("ABSLENGTH", arrEnergy2, arrSiliconAbsLength, nEntriesCnt2);
182 pMatSiliconPMT->SetMaterialPropertiesTable(pMPT);
183 pMatSiliconPMT->lock();
184 m_MapMaterials.emplace(matName,pMatSiliconPMT);
185
186
187 // Silicon
188 matName="Silicon";
189 GeoMaterial *pMatSilicon=new GeoMaterial(matName, 2.3290*g/cm3);
190 aSi=1.0*Si->getA()/(g/mole);
191 pMatSilicon->add(const_cast<GeoElement*> (Si),1.0);
192 pMatSilicon->lock();
193 m_MapMaterials.emplace(matName,pMatSilicon);
194
195 // Water
196 matName="Water";
197 GeoMaterial *pMatWater=new GeoMaterial(matName, 1.0*g/cm3);
198 aH=0.11*Si->getA()/(g/mole);
199 aO=0.89*Al->getA()/(g/mole);
200 Atot=aH+aO;
201 pMatWater->add(const_cast<GeoElement*> (H),aH/Atot);
202 pMatWater->add(const_cast<GeoElement*> (O),aO/Atot);
203 pMatWater->lock();
204 m_MapMaterials.emplace(matName,pMatWater);
205
206 // Beryllium
207 matName="Beryllium_AFP";
208 GeoMaterial* pMaterialBe=new GeoMaterial(matName, 1.848*CLHEP::g/CLHEP::cm3);
209
210 pMaterialBe->add(const_cast<GeoElement*> (Be), 1);
211 pMaterialBe->lock();
212 m_MapMaterials.emplace(matName,pMaterialBe);
213}
214
215
216void AFP_GeoModelFactory::create(GeoPhysVol *world)
217{
218 char szLabel[32];
219 StatusCode SCode;
221 HepGeom::Transform3D TransEnvInWorld;
222 HepGeom::Transform3D PosElementInEnv;
223
224 //define materials
226
227 // Initialization of Surface Container for TD Surface(s)
230
231 //AFP00 (SIDE A (+z)) ------------------------------------------------------------------------------------------------------------------------------------------------------
232
233 //Optical Envelope
234 TransEnvInWorld=m_pGeometry->getStationTransform("AFP00");
235 const GeoBox* pBoxLongEnv= new GeoBox(150*mm, 150*CLHEP::mm, 280*CLHEP::mm);
236 const GeoLogVol* pLogLongEnv = new GeoLogVol("AFP00_LogStationEnv", pBoxLongEnv, m_MapMaterials[std::string("OpticalVacuum")]);
237 GeoOpticalPhysVol* pPhysLongEnv = new GeoOpticalPhysVol(pLogLongEnv);
238 sprintf(szLabel,"AFP00_StationEnv");
239 world->add(new GeoTransform(Amg::CLHEPTransformToEigen(TransEnvInWorld)));
240 world->add(new GeoNameTag(szLabel));
241 world->add(pPhysLongEnv);
242 m_pDetectorManager->addTreeTop(pPhysLongEnv);
243
244 //Roman Pot
245 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP00",ESE_RPOT);
246 addRomanPot(pPhysLongEnv,"AFP00",PosElementInEnv);
247
248 //Timing detector
249 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP00",ESE_TOF);
250 SCode=addTimingDetector("AFP00",pPhysLongEnv,PosElementInEnv, pBSContainer);
251
252 //Silicon detector
253 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP00",ESE_SID);
254 addSiDetector(pPhysLongEnv,"AFP00",PosElementInEnv);
255
256 //AFP01 (SIDE A (+z)) ------------------------------------------------------------------------------------------------------------------------------------------------------
257
258 //add envelope -- short beampipe (station A)
259 TransEnvInWorld=m_pGeometry->getStationTransform("AFP01");
260 const GeoBox* pBoxShortEnv= new GeoBox(150*CLHEP::mm, 150*CLHEP::mm, 280*CLHEP::mm);
261 const GeoLogVol* pLogShortEnv = new GeoLogVol("AFP01_LogStationEnv", pBoxShortEnv, m_MapMaterials[std::string("std::Vacuum")]);
262 GeoPhysVol* pPhysShortEnv = new GeoPhysVol(pLogShortEnv);
263 sprintf(szLabel,"AFP01_StationEnv");
264 world->add(new GeoTransform(Amg::CLHEPTransformToEigen(TransEnvInWorld)));
265 world->add(new GeoNameTag(szLabel));
266 world->add(pPhysShortEnv);
267 m_pDetectorManager->addTreeTop(pPhysShortEnv);
268
269 //Roman Pot
270 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP01",ESE_RPOT);
271 addRomanPot(pPhysShortEnv,"AFP01",PosElementInEnv);
272
273 //Silicon detector
274 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP01",ESE_SID);
275 addSiDetector(pPhysShortEnv,"AFP01",PosElementInEnv);
276
277 //AFP02 (SIDE C (-z)) ------------------------------------------------------------------------------------------------------------------------------------------------------
278
279 //add envelope -- short beampipe (station C)
280 TransEnvInWorld=m_pGeometry->getStationTransform("AFP02");
281 const GeoBox* pBoxShortEnv1= new GeoBox(150*CLHEP::mm, 150*CLHEP::mm, 280*CLHEP::mm);
282 const GeoLogVol* pLogShortEnv1 = new GeoLogVol("AFP02_LogStationEnv", pBoxShortEnv1, m_MapMaterials[std::string("std::Vacuum")]);
283 GeoPhysVol* pPhysShortEnv1 = new GeoPhysVol(pLogShortEnv1);
284 sprintf(szLabel,"AFP02_StationEnv");
285 world->add(new GeoTransform(Amg::CLHEPTransformToEigen(TransEnvInWorld)));
286 world->add(new GeoNameTag(szLabel));
287 world->add(pPhysShortEnv1);
288 m_pDetectorManager->addTreeTop(pPhysShortEnv1);
289
290 //Roman Pot
291 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP02",ESE_RPOT);
292 addRomanPot(pPhysShortEnv1,"AFP02",PosElementInEnv);
293
294 //Silicon detector
295 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP02",ESE_SID);
296 addSiDetector(pPhysShortEnv1,"AFP02",PosElementInEnv);
297
298 //AFP03 (SIDE C (-z)) ------------------------------------------------------------------------------------------------------------------------------------------------------
299
300 // Optical Envelope
301 TransEnvInWorld=m_pGeometry->getStationTransform("AFP03");
302 const GeoBox* pBoxLongEnv1= new GeoBox(150*mm, 150*CLHEP::mm, 280*CLHEP::mm);
303 const GeoLogVol* pLogLongEnv1 = new GeoLogVol("AFP03_LogStationEnv", pBoxLongEnv1, m_MapMaterials[std::string("OpticalVacuum")]);
304 GeoOpticalPhysVol* pPhysLongEnv1 = new GeoOpticalPhysVol(pLogLongEnv1);
305 sprintf(szLabel,"AFP03_StationEnv");
306 world->add(new GeoTransform(Amg::CLHEPTransformToEigen(TransEnvInWorld)));
307 world->add(new GeoNameTag(szLabel));
308 world->add(pPhysLongEnv1);
309 m_pDetectorManager->addTreeTop(pPhysLongEnv1);
310
311 //Roman Pot
312 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP03",ESE_RPOT);
313 addRomanPot( pPhysLongEnv1,"AFP03",PosElementInEnv);
314
315 //Timing detector
316 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP03",ESE_TOF);
317 SCode=addTimingDetector("AFP03",pPhysLongEnv1,PosElementInEnv, pBSContainer);
318
319 //Silicon detector
320 PosElementInEnv=m_pGeometry->getStationElementTransform("AFP03",ESE_SID);
321 addSiDetector(pPhysLongEnv1,"AFP03",PosElementInEnv);
322
323
324
325 //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
326
327 // Register the Surface Container with the Detector Store
328 SCode=m_pDetectorStore->record(pBSContainer, "AFP_GeoModel");
329 if (SCode.isFailure()){
330
331 }
332}
333
338
339
341{
342
343}
@ ESE_RPOT
@ ESE_TOF
@ ESE_SID
#define cm3
#define mole
std::vector< GeoBorderSurface > GeoBorderSurfaceContainer
@ stateSolid
static Double_t P(Double_t *tt, Double_t *par)
#define H(x, y, z)
Definition MD5.cxx:114
std::map< std::string, GeoRef< const GeoMaterial > > m_MapMaterials
void addSiDetector(GeoPhysVol *pPhysMotherVol, const char *pszStationName, HepGeom::Transform3D &TransInMotherVolume)
void addRomanPot(GeoPhysVol *pPhysMotherVol, const char *pszStationName, HepGeom::Transform3D &TransInMotherVolume)
AFP_GeoModelFactory(StoreGateSvc *pDetStore, AFP_Geometry *pGeometry)
void updatePositions(AFP_BPMCOOLPARAMS *pBpmParams)
StatusCode addTimingDetector(const char *pszStationName, GeoOpticalPhysVol *pPhysMotherVol, HepGeom::Transform3D &TransInMotherVolume, GeoBorderSurfaceContainer *bsContainer)
AFP_CONFIGURATION m_CfgParams
virtual const AFP_GeoModelManager * getDetectorManager() const
virtual void create(GeoPhysVol *world)
AFP_GeoModelManager * m_pDetectorManager
StoreGateSvc * m_pDetectorStore
void getCfgParams(AFP_CONFIGURATION *pCfgParams) const
void SetMaterialPropertiesTable(GeoMaterialPropertiesTable *MPT)
void AddProperty(const char *key, double *PhotonMomenta, double *PropertyValues, int NumEntries)
Ensure that the extensions for the Vector3D are properly loaded.
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
struct color C
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
static constexpr double ToF_TrainsCnt
static constexpr double ToF_ColumnsCnt