MaterialPropertyLoader.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file MaterialPropertyLoader.cxx
3 //
4 /// \author bjpjones@mit.edu
5 ////////////////////////////////////////////////////////////////////////
6 // Class to set material properties for different materials in
7 // the detector. Currently mainly used to set optical properties
8 // for LAr and other optical components
9 //
10 
11 // TODO verify the inclusion list
16 
17 #include "Geant4/G4LogicalSkinSurface.hh"
18 #include "Geant4/G4LogicalVolume.hh"
19 #include "Geant4/G4LogicalVolumeStore.hh"
20 #include "Geant4/G4Material.hh"
21 #include "Geant4/G4MaterialPropertiesTable.hh"
22 #include "Geant4/G4OpticalSurface.hh"
23 
25 
26 namespace larg4 {
27 
28  //----------------------------------------------
29  void
32  std::map<double, double> PropertyVector,
33  double Unit)
34  {
35  std::map<double, double> PropVectorWithUnit;
36  for (std::map<double, double>::const_iterator it = PropertyVector.begin();
37  it != PropertyVector.end();
38  it++) {
39  PropVectorWithUnit[it->first * CLHEP::eV] = it->second * Unit;
40  }
41  fPropertyList[Material][Property] = PropVectorWithUnit;
42  // replace with MF_LOGDEBUG()
43  mf::LogInfo("MaterialPropertyLoader") << "Added property " << Material << " " << Property;
44  }
45 
46  //----------------------------------------------
47  void
50  double PropertyValue,
51  double Unit)
52  {
53  fConstPropertyList[Material][Property] = PropertyValue * Unit;
54  // replace with MF_LOGDEBUG()
55  mf::LogInfo("MaterialPropertyLoader")
56  << "Added const property " << Material << " " << Property << " = " << PropertyValue;
57  }
58 
59  //----------------------------------------------
60  void
61  MaterialPropertyLoader::SetBirksConstant(std::string Material, double PropertyValue, double Unit)
62  {
63  fBirksConstants[Material] = PropertyValue * Unit;
64  // replace with MF_LOGDEBUG()
65  mf::LogInfo("MaterialPropertyLoader") << "Set Birks constant " << Material;
66  }
67 
68  //----------------------------------------------
69  void
70  MaterialPropertyLoader::UpdateGeometry(G4LogicalVolumeStore* lvs)
71  {
72  std::map<std::string, G4MaterialPropertiesTable*> MaterialTables;
73  std::map<std::string, bool> MaterialsSet;
74 
75  // TODO replace console output with messagefacility output
76  mf::LogInfo("MaterialPropertyLoader") << "UPDATING GEOMETRY";
77 
78  // Loop over each material with a property vector and create a new material table for it
79  for (std::map<std::string, std::map<std::string, std::map<double, double>>>::const_iterator i =
80  fPropertyList.begin();
81  i != fPropertyList.end();
82  i++) {
83  std::string Material = i->first;
84  MaterialsSet[Material] = true;
85  MaterialTables[Material] = new G4MaterialPropertiesTable;
86  }
87 
88  // Loop over each material with a const property,
89  // if material table does not exist, create one
90  for (std::map<std::string, std::map<std::string, double>>::const_iterator i =
91  fConstPropertyList.begin();
92  i != fConstPropertyList.end();
93  i++) {
94  std::string Material = i->first;
95  if (!MaterialsSet[Material]) {
96  MaterialsSet[Material] = true;
97  MaterialTables[Material] = new G4MaterialPropertiesTable;
98  }
99  }
100 
101  // For each property vector, convert to an array of g4doubles and
102  // feed to materials table Lots of firsts and seconds! See annotation
103  // in MaterialPropertyLoader.h to follow what each element is
104 
105  for (std::map<std::string, std::map<std::string, std::map<double, double>>>::const_iterator i =
106  fPropertyList.begin();
107  i != fPropertyList.end();
108  i++) {
109  std::string Material = i->first;
110  for (std::map<std::string, std::map<double, double>>::const_iterator j = i->second.begin();
111  j != i->second.end();
112  j++) {
113  std::string Property = j->first;
114  std::vector<G4double> g4MomentumVector;
115  std::vector<G4double> g4PropertyVector;
116 
117  for (std::map<double, double>::const_iterator k = j->second.begin(); k != j->second.end();
118  k++) {
119  g4MomentumVector.push_back(k->first);
120  g4PropertyVector.push_back(k->second);
121  }
122  int NoOfElements = g4MomentumVector.size();
123  MaterialTables[Material]->AddProperty(
124  Property.c_str(), &g4MomentumVector[0], &g4PropertyVector[0], NoOfElements);
125  // replace with mf::LogVerbatim()
126  mf::LogInfo("MaterialPropertyLoader")
127  << "Added property " << Property << " to material table " << Material;
128  }
129  }
130 
131  //Add each const property element
132  for (std::map<std::string, std::map<std::string, double>>::const_iterator i =
133  fConstPropertyList.begin();
134  i != fConstPropertyList.end();
135  i++) {
136  std::string Material = i->first;
137  for (std::map<std::string, double>::const_iterator j = i->second.begin();
138  j != i->second.end();
139  j++) {
140  std::string Property = j->first;
141  G4double PropertyValue = j->second;
142  MaterialTables[Material]->AddConstProperty(Property.c_str(), PropertyValue);
143  // replace with mf::LogVerbatim()
144  mf::LogInfo("MaterialPropertyLoader")
145  << "Added const property " << Property << " to material table " << Material;
146  }
147  }
148 
149  //Loop through geometry elements and apply relevant material table where materials match
150  for (G4LogicalVolumeStore::iterator i = lvs->begin(); i != lvs->end(); ++i) {
151  G4LogicalVolume* volume = (*i);
152  G4Material* TheMaterial = volume->GetMaterial();
153  std::string Material = TheMaterial->GetName();
154 
155  //
156  // create reflective surfaces corresponding to the volumes made of some
157  // selected materials
158  //
159 
160  //--------------------------> FIXME <-----------------(parameters from fcl files(?))
161  G4MaterialPropertyVector* PropertyPointer = 0;
162  if (MaterialTables[Material])
163  PropertyPointer = MaterialTables[Material]->GetProperty("REFLECTIVITY");
164 
165  if (Material == "Copper") {
166  std::cout << "copper foil surface set " << volume->GetName() << std::endl;
167  if (PropertyPointer) {
168  std::cout << "defining Copper optical boundary " << std::endl;
169  G4OpticalSurface* refl_opsurfc =
170  new G4OpticalSurface("Surface copper", glisur, ground, dielectric_metal);
171  refl_opsurfc->SetMaterialPropertiesTable(MaterialTables[Material]);
172  refl_opsurfc->SetPolish(0.2);
173  new G4LogicalSkinSurface("refl_surfacec", volume, refl_opsurfc);
174  }
175  else
176  std::cout << "Warning: Copper surface in the geometry without REFLECTIVITY assigned"
177  << std::endl;
178  }
179 
180  if (Material == "G10") {
181  std::cout << "G10 surface set " << volume->GetName() << std::endl;
182  if (PropertyPointer) {
183  std::cout << "defining G10 optical boundary " << std::endl;
184  G4OpticalSurface* refl_opsurfg =
185  new G4OpticalSurface("g10 Surface", glisur, ground, dielectric_metal);
186  refl_opsurfg->SetMaterialPropertiesTable(MaterialTables[Material]);
187  refl_opsurfg->SetPolish(0.1);
188  new G4LogicalSkinSurface("refl_surfaceg", volume, refl_opsurfg);
189  }
190  else
191  std::cout << "Warning: G10 surface in the geometry without REFLECTIVITY assigned"
192  << std::endl;
193  }
194 
195  if (Material == "vm2000") {
196  std::cout << "vm2000 surface set " << volume->GetName() << std::endl;
197  if (PropertyPointer) {
198  std::cout << "defining vm2000 optical boundary " << std::endl;
199  G4OpticalSurface* refl_opsurf = new G4OpticalSurface(
200  "Reflector Surface", unified, groundfrontpainted, dielectric_dielectric);
201  refl_opsurf->SetMaterialPropertiesTable(MaterialTables[Material]);
202  G4double sigma_alpha = 0.8;
203  refl_opsurf->SetSigmaAlpha(sigma_alpha);
204  new G4LogicalSkinSurface("refl_surface", volume, refl_opsurf);
205  }
206  else
207  std::cout << "Warning: vm2000 surface in the geometry without REFLECTIVITY assigned"
208  << std::endl;
209  }
210  if (Material == "ALUMINUM_Al") {
211  std::cout << "ALUMINUM_Al surface set " << volume->GetName() << std::endl;
212  if (PropertyPointer) {
213  std::cout << "defining ALUMINUM_Al optical boundary " << std::endl;
214  G4OpticalSurface* refl_opsurfs =
215  new G4OpticalSurface("Surface Aluminum", glisur, ground, dielectric_metal);
216  refl_opsurfs->SetMaterialPropertiesTable(MaterialTables[Material]);
217  refl_opsurfs->SetPolish(0.5);
218  new G4LogicalSkinSurface("refl_surfaces", volume, refl_opsurfs);
219  }
220  else
221  std::cout << "Warning: ALUMINUM_Al surface in the geometry without REFLECTIVITY assigned"
222  << std::endl;
223  }
224  if (Material == "STEEL_STAINLESS_Fe7Cr2Ni") {
225  std::cout << "STEEL_STAINLESS_Fe7Cr2Ni surface set " << volume->GetName() << std::endl;
226  if (PropertyPointer) {
227  std::cout << "defining STEEL_STAINLESS_Fe7Cr2Ni optical boundary " << std::endl;
228  G4OpticalSurface* refl_opsurfs =
229  new G4OpticalSurface("Surface Steel", glisur, ground, dielectric_metal);
230  refl_opsurfs->SetMaterialPropertiesTable(MaterialTables[Material]);
231  refl_opsurfs->SetPolish(0.5);
232  new G4LogicalSkinSurface("refl_surfaces", volume, refl_opsurfs);
233  }
234  else
235  std::cout << "Warning: STEEL_STAINLESS_Fe7Cr2Ni surface in the geometry without "
236  "REFLECTIVITY assigned"
237  << std::endl;
238  }
239  //-----------------------------------------------------------------------------
240 
241  //
242  // apply the remaining material properties
243  //
245  MaterialTables.begin();
246  j != MaterialTables.end();
247  j++) {
248  if (Material == j->first) {
249  TheMaterial->SetMaterialPropertiesTable(j->second);
250  //Birks Constant, for some reason, must be set separately
251  if (fBirksConstants[Material] != 0)
252  TheMaterial->GetIonisation()->SetBirksConstant(fBirksConstants[Material]);
253  volume->SetMaterial(TheMaterial);
254  }
255  }
256  }
257  }
258 
259  void
261  std::string /*Material*/,
262  std::map<std::string, std::map<double, double>> Reflectances,
263  std::map<std::string, std::map<double, double>> DiffuseFractions)
264  {
265  std::map<double, double> ReflectanceToStore;
266  std::map<double, double> DiffuseToStore;
267 
268  for (std::map<std::string, std::map<double, double>>::const_iterator itMat =
269  Reflectances.begin();
270  itMat != Reflectances.end();
271  ++itMat) {
272  std::string ReflectancePropName = std::string("REFLECTANCE_") + itMat->first;
273  ReflectanceToStore.clear();
274  for (std::map<double, double>::const_iterator itEn = itMat->second.begin();
275  itEn != itMat->second.end();
276  ++itEn) {
277  ReflectanceToStore[itEn->first] = itEn->second;
278  }
279  SetMaterialProperty("LAr", ReflectancePropName, ReflectanceToStore, 1);
280  }
281 
282  for (std::map<std::string, std::map<double, double>>::const_iterator itMat =
283  DiffuseFractions.begin();
284  itMat != DiffuseFractions.end();
285  ++itMat) {
286  std::string DiffusePropName = std::string("DIFFUSE_REFLECTANCE_FRACTION_") + itMat->first;
287  DiffuseToStore.clear();
288  for (std::map<double, double>::const_iterator itEn = itMat->second.begin();
289  itEn != itMat->second.end();
290  ++itEn) {
291  DiffuseToStore[itEn->first] = itEn->second;
292  }
293  SetMaterialProperty("LAr", DiffusePropName, DiffuseToStore, 1);
294  }
295  }
296 
297  void
299  std::map<std::string, std::map<double, double>> Reflectances)
300  {
301  std::map<double, double> ReflectanceToStore;
302 
303  for (std::map<std::string, std::map<double, double>>::const_iterator itMat =
304  Reflectances.begin();
305  itMat != Reflectances.end();
306  ++itMat) {
307  ReflectanceToStore.clear();
308  for (std::map<double, double>::const_iterator itEn = itMat->second.begin();
309  itEn != itMat->second.end();
310  ++itEn) {
311  ReflectanceToStore[itEn->first] = itEn->second;
312  }
313  SetMaterialProperty(itMat->first, "REFLECTIVITY", ReflectanceToStore, 1);
314  }
315  }
316 
317  void
319  {
320  const detinfo::LArProperties* LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
321 
322  // wavelength dependent quantities
323 
324  SetMaterialProperty("LAr", "FASTCOMPONENT", LarProp->FastScintSpectrum(), 1);
325  SetMaterialProperty("LAr", "SLOWCOMPONENT", LarProp->SlowScintSpectrum(), 1);
326  SetMaterialProperty("LAr", "RINDEX", LarProp->RIndexSpectrum(), 1);
327  SetMaterialProperty("LAr", "ABSLENGTH", LarProp->AbsLengthSpectrum(), CLHEP::cm);
328  SetMaterialProperty("LAr", "RAYLEIGH", LarProp->RayleighSpectrum(), CLHEP::cm);
329 
330  // scalar properties
331 
333  "SCINTILLATIONYIELD",
334  LarProp->ScintYield(true),
335  1 / CLHEP::MeV); // true = scaled down by prescale in larproperties
336  SetMaterialConstProperty("LAr", "RESOLUTIONSCALE", LarProp->ScintResolutionScale(), 1);
337  SetMaterialConstProperty("LAr", "FASTTIMECONSTANT", LarProp->ScintFastTimeConst(), CLHEP::ns);
338  SetMaterialConstProperty("LAr", "SLOWTIMECONSTANT", LarProp->ScintSlowTimeConst(), CLHEP::ns);
339  SetMaterialConstProperty("LAr", "YIELDRATIO", LarProp->ScintYieldRatio(), 1);
340  SetMaterialConstProperty("LAr", "ELECTRICFIELD", detProp.Efield(), CLHEP::kilovolt / CLHEP::cm);
341 
343  if (detProp.SimpleBoundary())
345  "LAr", LarProp->SurfaceReflectances(), LarProp->SurfaceReflectanceDiffuseFractions());
346  else
348 
349  // If we are using scint by particle type, load these
350 
351  if (LarProp->ScintByParticleType()) {
352  // true = scaled down by prescale in larproperties
354  "LAr", "PROTONSCINTILLATIONYIELD", LarProp->ProtonScintYield(true), 1. / CLHEP::MeV);
355  SetMaterialConstProperty("LAr", "PROTONYIELDRATIO", LarProp->ProtonScintYieldRatio(), 1.);
357  "LAr", "MUONSCINTILLATIONYIELD", LarProp->MuonScintYield(true), 1. / CLHEP::MeV);
358  SetMaterialConstProperty("LAr", "MUONYIELDRATIO", LarProp->MuonScintYieldRatio(), 1.);
360  "LAr", "KAONSCINTILLATIONYIELD", LarProp->KaonScintYield(true), 1. / CLHEP::MeV);
361  SetMaterialConstProperty("LAr", "KAONYIELDRATIO", LarProp->KaonScintYieldRatio(), 1.);
363  "LAr", "PIONSCINTILLATIONYIELD", LarProp->PionScintYield(true), 1. / CLHEP::MeV);
364  SetMaterialConstProperty("LAr", "PIONYIELDRATIO", LarProp->PionScintYieldRatio(), 1.);
366  "LAr", "ELECTRONSCINTILLATIONYIELD", LarProp->ElectronScintYield(true), 1. / CLHEP::MeV);
367  SetMaterialConstProperty("LAr", "ELECTRONYIELDRATIO", LarProp->ElectronScintYieldRatio(), 1.);
369  "LAr", "ALPHASCINTILLATIONYIELD", LarProp->AlphaScintYield(true), 1. / CLHEP::MeV);
370  SetMaterialConstProperty("LAr", "ALPHAYIELDRATIO", LarProp->AlphaScintYieldRatio(), 1.);
371  }
372 
373  // If we are simulating the TPB load this
374 
375  if (LarProp->ExtraMatProperties()) {
376  SetMaterialProperty("TPB", "RINDEX", LarProp->RIndexSpectrum(), 1);
377  SetMaterialProperty("TPB", "WLSABSLENGTH", LarProp->TpbAbs(), CLHEP::m);
378  SetMaterialProperty("TPB", "WLSCOMPONENT", LarProp->TpbEm(), 1);
379 
380  SetMaterialConstProperty("TPB", "WLSTIMECONSTANT", LarProp->TpbTimeConstant(), CLHEP::ns);
381  }
382  }
383 
384 }
static constexpr double cm
Definition: Units.h:68
intermediate_table::iterator iterator
virtual double ElectronScintYieldRatio() const =0
virtual double ScintYieldRatio() const =0
virtual double AlphaScintYield(bool prescale=false) const =0
virtual std::map< double, double > AbsLengthSpectrum() const =0
void SetMaterialProperty(std::string Material, std::string Property, std::map< double, double > Values, double Unit)
Stores the specified emergy-dependent material property.
virtual std::map< double, double > RayleighSpectrum() const =0
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
virtual std::map< double, double > RIndexSpectrum() const =0
virtual double AlphaScintYieldRatio() const =0
void GetPropertiesFromServices(detinfo::DetectorPropertiesData const &detProp)
Imports properties from LArSoft services.
virtual double ScintSlowTimeConst() const =0
std::map< std::string, std::map< std::string, std::map< double, double > > > fPropertyList
static const std::string volume[nvol]
virtual double ScintFastTimeConst() const =0
Geant4 interface.
intermediate_table::const_iterator const_iterator
static constexpr double MeV
Definition: Units.h:129
virtual double ProtonScintYieldRatio() const =0
void SetMaterialConstProperty(std::string Material, std::string Property, double Value, double Unit)
Stores the specified material property.
kilovolt_as<> kilovolt
Type of potential stored in kilovolt, in double precision.
virtual double ScintResolutionScale() const =0
double Efield(unsigned int planegap=0) const
kV/cm
virtual double ProtonScintYield(bool prescale=false) const =0
virtual double PionScintYieldRatio() const =0
std::map< std::string, std::map< std::string, double > > fConstPropertyList
virtual bool ExtraMatProperties() const =0
static constexpr double eV
Definition: Units.h:127
virtual double ScintBirksConstant() const =0
virtual double ElectronScintYield(bool prescale=false) const =0
virtual double PionScintYield(bool prescale=false) const =0
virtual std::map< double, double > TpbEm() const =0
virtual double TpbTimeConstant() const =0
virtual std::map< std::string, std::map< double, double > > SurfaceReflectances() const =0
void UpdateGeometry(G4LogicalVolumeStore *lvs)
Updates the material properties with the collected values.
virtual std::map< double, double > SlowScintSpectrum() const =0
virtual double MuonScintYield(bool prescale=false) const =0
virtual double KaonScintYield(bool prescale=false) const =0
virtual std::map< double, double > TpbAbs() const =0
virtual double ScintYield(bool prescale=false) const =0
virtual double MuonScintYieldRatio() const =0
void SetReflectances(std::string, std::map< std::string, std::map< double, double >>, std::map< std::string, std::map< double, double >>)
virtual std::map< std::string, std::map< double, double > > SurfaceReflectanceDiffuseFractions() const =0
void SetBirksConstant(std::string, double, double)
virtual double KaonScintYieldRatio() const =0
std::map< std::string, double > fBirksConstants
virtual bool ScintByParticleType() const =0
QAsciiDict< Entry > ns
Definition: types.h:32
virtual std::map< double, double > FastScintSpectrum() const =0
QTextStream & endl(QTextStream &s)