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