ATLAS Offline Software
Loading...
Searching...
No Matches
InDetMaterialManager Class Reference

InDetMaterialManager. More...

#include <InDetMaterialManager.h>

Inheritance diagram for InDetMaterialManager:
Collaboration diagram for InDetMaterialManager:

Classes

class  MaterialByWeight
class  MaterialComponent
class  MaterialDef
 Class to hold information need to create a material. More...

Public Member Functions

 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore)
 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore, const IRDBRecordset_ptr &weightTable, const std::string &space="", bool extraFunctionality=false)
 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore, const IRDBRecordset_ptr &weightTable, const IRDBRecordset_ptr &compositionTable, const std::string &space="")
 InDetMaterialManager (const std::string &managerName, InDetDD::AthenaComps *)
 ~InDetMaterialManager ()
void addWeightTable (const IRDBRecordset_ptr &weightTable, const std::string &space="")
void addWeightMaterial (const std::string &materialName, const std::string &materialBase, double weight, int linearWeightFlag)
void addCompositionTable (const IRDBRecordset_ptr &compositionTable, const std::string &space="")
void addScalingTable (const IRDBRecordset_ptr &scalingTable)
bool hasMaterial (const std::string &materialName) const
const GeoMaterial * getMaterial (const std::string &materialName)
 Get material. First looks for locally defined material and if not found looks in GeoModel material manager.
const GeoElement * getElement (const std::string &elementName)
 Get element from GeoModel material manager.
const GeoMaterial * getMaterial (const std::string &origMaterialName, double density, const std::string &newName="")
 Create and get material with a specified density based on an existing material.
const GeoMaterial * getMaterialScaled (const std::string &origMaterialName, double scaleFactor, const std::string &newName="")
const GeoMaterial * getMaterialForVolume (const std::string &materialName, double volume, const std::string &newName="")
 Create and get material with a density calculated to give weight in predefined weight table.
const GeoMaterial * getMaterialForVolumeLength (const std::string &materialName, double volume, double length, const std::string &newName="")
const GeoMaterial * getMaterialForVolumeLength (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &factors, double volume, double length)
const GeoMaterial * getMaterialForVolumeLength (const std::string &name, const std::string &materialComponent, double factor, double volume, double length)
const GeoMaterial * getCompositeMaterialForVolume (const std::string &newMatName, const double volumeTot, const double volume1, const std::string &matName1, const double volume2, const std::string &matName2)
const GeoMaterial * getMaterial (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &fractWeights, double density)
void addMaterial (GeoMaterial *material)
 Add material.
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Types

using MaterialStore = std::map<std::string, GeoIntrusivePtr<const GeoMaterial>>
typedef std::map< std::string, MaterialByWeightMaterialWeightMap
typedef std::map< std::string, MaterialComponentMaterialCompositionMap
typedef std::map< std::string, double > ExtraScaleFactorMap

Private Member Functions

StoredMaterialManagerretrieveManager (const StoreGateSvc *detStore)
const GeoMaterial * getAdditionalMaterial (const std::string &materialName) const
bool compareDensity (double d1, double d2) const
const GeoMaterial * getMaterialInternal (const std::string &materialName)
const GeoMaterial * getMaterialInternal (const std::string &origMaterialName, double density, const std::string &newName="")
const GeoMaterial * getMaterialScaledInternal (const std::string &origMaterialName, double scaleFactor, const std::string &newName="")
const GeoMaterial * getMaterialInternal (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &fractWeights, double density)
const GeoMaterial * extraScaledMaterial (const std::string &materialName, const std::string &newName, const GeoMaterial *origMaterial)
const GeoMaterial * extraScaledMaterial (const std::string &materialName, const GeoMaterial *origMaterial)
void createMaterial (const MaterialDef &material)
double getExtraScaleFactor (const std::string &materialName)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

StoredMaterialManagerm_materialManager
std::string m_managerName
MaterialStore m_store
MaterialWeightMap m_weightMap
MaterialCompositionMap m_matCompositionMap
ExtraScaleFactorMap m_scalingMap
bool m_extraFunctionality
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging)

Detailed Description

InDetMaterialManager.

This provides an interface to the GeoModel Material Manager as well as allowing additional materials to be defined or standard ones redefined. It also allows creating new materials based on existing ones but with a different density. It is also possible to specify a weight table and this is used to create materials with a density such that the the total weight is correct.

Definition at line 32 of file InDetMaterialManager.h.

Member Typedef Documentation

◆ ExtraScaleFactorMap

typedef std::map<std::string, double > InDetMaterialManager::ExtraScaleFactorMap
private

Definition at line 220 of file InDetMaterialManager.h.

◆ MaterialCompositionMap

typedef std::map<std::string, MaterialComponent > InDetMaterialManager::MaterialCompositionMap
private

Definition at line 217 of file InDetMaterialManager.h.

◆ MaterialStore

using InDetMaterialManager::MaterialStore = std::map<std::string, GeoIntrusivePtr<const GeoMaterial>>
private

Definition at line 211 of file InDetMaterialManager.h.

◆ MaterialWeightMap

typedef std::map<std::string, MaterialByWeight > InDetMaterialManager::MaterialWeightMap
private

Definition at line 214 of file InDetMaterialManager.h.

Constructor & Destructor Documentation

◆ InDetMaterialManager() [1/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore )

Definition at line 27 of file InDetMaterialManager.cxx.

29 : AthMessaging(managerName),
30 m_managerName(managerName),
32{
34}
AthMessaging()
Default constructor:
StoredMaterialManager * retrieveManager(const StoreGateSvc *detStore)
StoredMaterialManager * m_materialManager

◆ InDetMaterialManager() [2/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore,
const IRDBRecordset_ptr & weightTable,
const std::string & space = "",
bool extraFunctionality = false )

Definition at line 37 of file InDetMaterialManager.cxx.

42 : AthMessaging(managerName),
43 m_managerName(managerName),
44 m_extraFunctionality(extraFunctionality)
45{
47
48 if (weightTable) addWeightTable(weightTable, space);
49
50 // For testing we add a few materials.
51 //m_weightMap["sct::CoolingBlock"] = MaterialByWeight(2.418*CLHEP::gram);
52 //m_weightMap["sct::CoolingBlock"] = MaterialByWeight(2*CLHEP::gram);
53 //m_weightMap["sct::BrlHybrid"] = MaterialByWeight("sct::Hybrid", 8*CLHEP::gram);
54 //m_weightMap["sct::FwdHybrid"] = MaterialByWeight("std::Carbon", 7.662*CLHEP::gram);
55}
void addWeightTable(const IRDBRecordset_ptr &weightTable, const std::string &space="")

◆ InDetMaterialManager() [3/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore,
const IRDBRecordset_ptr & weightTable,
const IRDBRecordset_ptr & compositionTable,
const std::string & space = "" )

Definition at line 57 of file InDetMaterialManager.cxx.

61 : AthMessaging(managerName),
62 m_managerName(managerName),
64{
66
67 if (weightTable) addWeightTable(weightTable, space);
68 if (compositionTable) addCompositionTable(compositionTable, space);
69}
void addCompositionTable(const IRDBRecordset_ptr &compositionTable, const std::string &space="")

◆ InDetMaterialManager() [4/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
InDetDD::AthenaComps * athenaComps )

Definition at line 71 of file InDetMaterialManager.cxx.

73 : AthMessaging(managerName),
74 m_managerName(managerName),
76{
78}
const StoreGateSvc * detStore() const

◆ ~InDetMaterialManager()

InDetMaterialManager::~InDetMaterialManager ( )
default

Member Function Documentation

◆ addCompositionTable()

void InDetMaterialManager::addCompositionTable ( const IRDBRecordset_ptr & compositionTable,
const std::string & space = "" )

Definition at line 388 of file InDetMaterialManager.cxx.

388 {
389 ATH_MSG_DEBUG("Reading in composition table: " << compositionTable->nodeName());
390
391 for (const auto& rec : *compositionTable) {
392 std::string materialName = rec->getString("MATERIAL");
393 if (!space.empty()) {
394 materialName = space + "::" + materialName;
395 }
396
397 std::string componentName = rec->getString("COMPONENT");
398 int count = rec->getInt("COUNT");
399 double factor = rec->getDouble("FACTOR");
400 double actualLength = rec->getDouble("ACTUALLENGTH");
401
402 m_matCompositionMap.insert(std::pair<std::string, MaterialComponent>(materialName,
403 MaterialComponent(componentName,
404 count * factor,
405 actualLength)));
406 }
407}
#define ATH_MSG_DEBUG(x)
virtual std::string nodeName() const =0
MaterialCompositionMap m_matCompositionMap
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146

◆ addMaterial()

void InDetMaterialManager::addMaterial ( GeoMaterial * material)

Add material.

Definition at line 301 of file InDetMaterialManager.cxx.

301 {
302 GeoIntrusivePtr<const GeoMaterial> matPtr{material};
303 std::string name(material->getName());
304 if (m_store.find(name) != m_store.end()) {
305 ATH_MSG_WARNING("Ignoring attempt to redefine an existing material: " << name);
306 // Delete the material if it is not already ref counted.
307 //std::cout << m_store[name] << std::endl;
308 } else {
309 material->lock();
310 m_store[name] = std::move(matPtr);
311
312 ATH_MSG_DEBUG("Created new material: " << name << ", " << material->getDensity() /
313 (Gaudi::Units::g / Gaudi::Units::cm3) << " g/cm3");
314 }
315}
#define ATH_MSG_WARNING(x)

◆ addScalingTable()

void InDetMaterialManager::addScalingTable ( const IRDBRecordset_ptr & scalingTable)

Definition at line 410 of file InDetMaterialManager.cxx.

410 {
411 if (!scalingTable || scalingTable->size()==0) return;
412 ATH_MSG_DEBUG("Reading in extra material scaling table: " << scalingTable->nodeName());
413 for (const auto& rec : *scalingTable) {
414 std::string materialName = rec->getString("MATERIAL");
415 double scalingFactor = rec->getDouble("FACTOR");
416
417 if (scalingFactor >= 0 || scalingFactor == 1) {
418 ATH_MSG_DEBUG("Material " << materialName << " will be scaled by: " << scalingFactor);
419 } else {
420 // -ve or scalefactor = 1 means will not be scaled.
421 ATH_MSG_DEBUG("Material " << materialName << " will be NOT be scaled.");
422 }
423 if (m_scalingMap.find(materialName) != m_scalingMap.end()) {
424 ATH_MSG_WARNING("Overriding material: " << materialName << " which already exists in scaling table");
425 }
426 m_scalingMap[materialName] = scalingFactor;
427 }
428}
virtual unsigned int size() const =0
ExtraScaleFactorMap m_scalingMap

◆ addWeightMaterial()

void InDetMaterialManager::addWeightMaterial ( const std::string & materialName,
const std::string & materialBase,
double weight,
int linearWeightFlag )

Definition at line 371 of file InDetMaterialManager.cxx.

372 {
373 // Weight in gr
374 weight = weight * GeoModelKernelUnits::gram;
375
376 if (m_weightMap.find(materialName) != m_weightMap.end()) {
377 ATH_MSG_WARNING("Material: " << materialName << " already exists in weight table");
378 } else {
379 ATH_MSG_DEBUG("Adding " << materialName
380 << " weight " << weight
381 << " linearWeightFlag " << linearWeightFlag
382 << " to weight table");
383 m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag);
384 }
385}
MaterialWeightMap m_weightMap

◆ addWeightTable()

void InDetMaterialManager::addWeightTable ( const IRDBRecordset_ptr & weightTable,
const std::string & space = "" )

Definition at line 326 of file InDetMaterialManager.cxx.

326 {
327 ATH_MSG_DEBUG("Reading in weight table: " << weightTable->nodeName());
328 for(const auto& rec : *weightTable) {
329 std::string materialName = rec->getString("MATERIAL");
330 if (!space.empty()) {
331 materialName = space + "::" + materialName;
332 }
333 std::string materialBase;
334 try {
335 if (!rec->isFieldNull("BASEMATERIAL")) {
336 materialBase = rec->getString("BASEMATERIAL");
337 }
338 }
339 catch(std::runtime_error&) {
340 ATH_MSG_DEBUG(weightTable->nodeName() << " table has no column named BASEMATERIAL");
341 }
342 double weight = rec->getDouble("WEIGHT") * GeoModelKernelUnits::gram;
343
344 bool linearWeightFlag = false;
346 try {
347 if(!rec->isFieldNull("LINWEIGHTFLAG")) {
348 linearWeightFlag = rec->getInt("LINWEIGHTFLAG");
349 }
350 }
351 catch(std::runtime_error&) {
352 ATH_MSG_DEBUG(weightTable->nodeName() << " table has no column named LINWEIGHTFLAG");
353 }
354 }
355
356 if (m_weightMap.find(materialName) != m_weightMap.end()) {
357 ATH_MSG_WARNING("Material: " << materialName << " already exists in weight table");
358 } else {
359 ATH_MSG_DEBUG("Adding " << materialName
360 << " weight " << weight
361 << " linearWeightFlag " << linearWeightFlag
362 << " raw weight " << rec->getDouble("WEIGHT")
363 << " m_extraFunctionality " << m_extraFunctionality
364 << " to weight table");
365 m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag);
366 }
367 }
368}

◆ compareDensity()

bool InDetMaterialManager::compareDensity ( double d1,
double d2 ) const
private

Definition at line 318 of file InDetMaterialManager.cxx.

318 {
319 if (close_to_zero(d2)){
320 throw (std::runtime_error("InDetMaterialManager:compareDensity: Density is zero"));
321 }
322 return(std::abs(d1 / d2 - 1.) < 1e-5);
323}
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())

◆ createMaterial()

void InDetMaterialManager::createMaterial ( const MaterialDef & material)
private

Definition at line 696 of file InDetMaterialManager.cxx.

696 {
697 if (material.numComponents() == 0) {
698 ATH_MSG_ERROR("Material has no components: " << material.name());
699 return;
700 }
701
702 // If total of fractions is greater than 1.1 then assume material is define by ratio of atoms.
703 double totWeight = material.totalFraction();
704 bool byAtomicRatio = false;
705 if (totWeight > 1.1) {
706 byAtomicRatio = true;
707 for (unsigned int i = 0; i < material.numComponents(); i++) {
708 if (material.compName(i).find("::") != std::string::npos) {
709 // If component name has "::" in it then its not an element.
710 ATH_MSG_ERROR("Material, " << material.name() <<
711 ", is assumed to be defined by atomic ratio (due to total fraction > 1)"
712 " but component is not an element: " << material.compName(i));
713 return;
714 }
715 const GeoElement* element = getElement(material.compName(i));
716 if (!element) {
717 ATH_MSG_ERROR("Error making material " << material.name() << ". Element not found: " <<
718 material.compName(i));
719 return;
720 }
721 totWeight += material.fraction(i) * element->getA();
722 }
723 } else {
724 // Check if total fraction is close to 1.
725 if (std::abs(totWeight - 1) > 0.01) {
726 ATH_MSG_WARNING("Total fractional weight does not sum to 1. Will renormalize. Total = " << totWeight);
727 }
728 }
729 // Now build the material
730 GeoIntrusivePtr<GeoMaterial> newMaterial{new GeoMaterial(material.name(), material.density())};
731 ATH_MSG_DEBUG("Creating material: " << material.name() << " with density: "
732 << material.density() / (Gaudi::Units::g / Gaudi::Units::cm3));
733 if (close_to_zero(totWeight)){
734 ATH_MSG_ERROR("totWeight is zero in InDetMaterialManager::createMaterial");
735 return;
736 }
737 for (unsigned int i = 0; i < material.numComponents(); i++) {
738 double fracWeight = material.fraction(i) / totWeight;
739 if (material.compName(i).find("::") == std::string::npos) {
740 const GeoElement* element = getElement(material.compName(i));
741 if (!element) {
742 ATH_MSG_ERROR("Error making material " << material.name() << ". Element not found: " << material.compName(i));
743 // delete the partially created material
744 return;
745 }
746 if (byAtomicRatio) {
747 fracWeight = material.fraction(i) * element->getA() / totWeight;
748 }
749 newMaterial->add(const_cast<GeoElement*>(element), fracWeight);
750 ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
751 } else {
752 GeoIntrusivePtr<const GeoMaterial> materialTmp{getMaterialInternal(material.compName(i))};
753 if (!materialTmp) {
754 ATH_MSG_ERROR("Error making material " << material.name() << ". Component not found: " << material.compName(i));
755 // delete the partially created material
756 return;
757 }
758 if (byAtomicRatio) {
759 // Should not happen as already checked that all components were elements.
760 ATH_MSG_ERROR("Unexpected Error");
761 }
762 newMaterial->add(const_cast<GeoMaterial*>(materialTmp.get()), fracWeight);
763 ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
764 }
765 }
766 newMaterial->lock();
767 addMaterial(newMaterial);
768}
#define ATH_MSG_ERROR(x)
const GeoElement * getElement(const std::string &elementName)
Get element from GeoModel material manager.
const GeoMaterial * getMaterialInternal(const std::string &materialName)
void addMaterial(GeoMaterial *material)
Add material.

◆ extraScaledMaterial() [1/2]

const GeoMaterial * InDetMaterialManager::extraScaledMaterial ( const std::string & materialName,
const GeoMaterial * origMaterial )
private

Definition at line 816 of file InDetMaterialManager.cxx.

816 {
817 if (!origMaterial) throw std::runtime_error(std::string("Invalid material: ") + materialName);
818
819 double scaleFactor = getExtraScaleFactor(materialName);
820 // -1 (or any -ve number) indicates material is not scaled. And if the scale factor
821 // is 1 then there is no need to create a new material.
822 if (scaleFactor < 0 || scaleFactor == 1 || materialName.find("Ether") != std::string::npos) return origMaterial;
823
824 if (scaleFactor == 0) return getMaterialInternal("std::Vacuum");
825
826 std::string newName = materialName + "_ExtraScaling";
827
828 // Check if it is already made.
829 const GeoMaterial* newMaterial = getAdditionalMaterial(newName);
830
831 // Already made so we return it.
832 if (newMaterial) return newMaterial;
833
834 // Otherwise we need to make it.
835 double density = origMaterial->getDensity() * scaleFactor;
836
837 // create new material
838 GeoMaterial* newMaterialTmp = new GeoMaterial(newName, density);
839 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.);
840 addMaterial(newMaterialTmp);
841 newMaterial = newMaterialTmp;
842
843 return newMaterial;
844}
double getExtraScaleFactor(const std::string &materialName)
const GeoMaterial * getAdditionalMaterial(const std::string &materialName) const

◆ extraScaledMaterial() [2/2]

const GeoMaterial * InDetMaterialManager::extraScaledMaterial ( const std::string & materialName,
const std::string & newName,
const GeoMaterial * origMaterial )
private

Definition at line 805 of file InDetMaterialManager.cxx.

807 {
808 if (newName.empty()) {
809 return extraScaledMaterial(materialName, origMaterial);
810 } else {
811 return extraScaledMaterial(newName, origMaterial);
812 }
813}
const GeoMaterial * extraScaledMaterial(const std::string &materialName, const std::string &newName, const GeoMaterial *origMaterial)

◆ getAdditionalMaterial()

const GeoMaterial * InDetMaterialManager::getAdditionalMaterial ( const std::string & materialName) const
private

Definition at line 126 of file InDetMaterialManager.cxx.

126 {
127 MaterialStore::const_iterator iter;
128 if ((iter = m_store.find(materialName)) != m_store.end()) {
129 return iter->second;
130 } else {
131 return nullptr;
132 }
133}

◆ getCompositeMaterialForVolume()

const GeoMaterial * InDetMaterialManager::getCompositeMaterialForVolume ( const std::string & newMatName,
const double volumeTot,
const double volume1,
const std::string & matName1,
const double volume2,
const std::string & matName2 )

Definition at line 136 of file InDetMaterialManager.cxx.

140 {
141 std::vector<std::string> baseMaterials;
142 std::vector<double> fracWeight;
143 baseMaterials.reserve(2);
144 fracWeight.reserve(2);
145
146 ATH_MSG_DEBUG("Composite material : " << volumeTot / Gaudi::Units::cm3 << " = " << volume1 / Gaudi::Units::cm3
147 << " + " << volume2 / Gaudi::Units::cm3);
148 ATH_MSG_DEBUG("Composite material : " << matName1 << " " << matName2);
149
150 double density1, density2;
151
152 MaterialWeightMap::const_iterator iter;
153 if ((iter = m_weightMap.find(matName1)) != m_weightMap.end()) {
154 const GeoMaterial* mat1 = getMaterialForVolume(matName1, volume1);
155 density1 = mat1->getDensity();
156 ATH_MSG_DEBUG("Composite material 1 - weight : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
157 } else {
158 const GeoMaterial* mat1 = getMaterial(matName1);
159 density1 = mat1->getDensity();
160 ATH_MSG_DEBUG("Composite material 1 - standard : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
161 }
162
163 if ((iter = m_weightMap.find(matName2)) != m_weightMap.end()) {
164 const GeoMaterial* mat2 = getMaterialForVolume(matName2, volume2);
165 density2 = mat2->getDensity();
166 ATH_MSG_DEBUG("Composite material 2 - weight : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
167 } else {
168 const GeoMaterial* mat2 = getMaterial(matName2);
169 density2 = mat2->getDensity();
170 ATH_MSG_DEBUG("Composite material 2 - standard : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
171 }
172
173 double weight1 = density1 * volume1;
174 double weight2 = density2 * volume2;
175 double invWeightTot = 1.0 / (weight1 + weight2);
176
177 double density = (weight1 + weight2) / volumeTot;
178
179 double frac1 = weight1 / (weight1 + weight2);
180 double frac2 = weight2 / (weight1 + weight2);
181 double density_2 = 1.0 / (frac1 / density1 + frac2 / density2);
182 double density_3 = (weight1 + weight2) / (volume1 + volume2);
183 ATH_MSG_DEBUG("-> weights : " << weight1 / (GeoModelKernelUnits::gram) << " " << weight2 / (GeoModelKernelUnits::gram));
184 ATH_MSG_DEBUG("-> density : " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_2 /
185 (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_3 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
186
187
188 baseMaterials.push_back(matName1);
189 baseMaterials.push_back(matName2);
190 fracWeight.push_back(weight1 * invWeightTot);
191 fracWeight.push_back(weight2 * invWeightTot);
192
193 return getMaterial(newMatName, baseMaterials, fracWeight, density);
194}
const GeoMaterial * getMaterialForVolume(const std::string &materialName, double volume, const std::string &newName="")
Create and get material with a density calculated to give weight in predefined weight table.
const GeoMaterial * getMaterial(const std::string &materialName)
Get material. First looks for locally defined material and if not found looks in GeoModel material ma...

◆ getElement()

const GeoElement * InDetMaterialManager::getElement ( const std::string & elementName)

Get element from GeoModel material manager.

Definition at line 88 of file InDetMaterialManager.cxx.

88 {
90 std::string errorMessage("Null pointer to Stored Material Manager!");
91 ATH_MSG_FATAL(errorMessage);
92 throw std::runtime_error(errorMessage);
93 }
94 return m_materialManager->getElement(elementName);
95}
#define ATH_MSG_FATAL(x)

◆ getExtraScaleFactor()

double InDetMaterialManager::getExtraScaleFactor ( const std::string & materialName)
private

Definition at line 847 of file InDetMaterialManager.cxx.

847 {
848 // If name is found in map we return the corresponding scale factor.
849 // The special name "ALL" indicates all materials are scaled.
850 // Individual materials can be excluded from scaling by giving either
851 // a -ve scaling factor or just specifying a scaling factor of 1.
852 // A scaling factor of 0 means the material will be replaced by vacuum.
853
854 ExtraScaleFactorMap::const_iterator iter = m_scalingMap.find(materialName);
855 if (iter != m_scalingMap.end()) {
856 return iter->second;
857 } else {
858 // Check for special names
859 // ALL means everything scaled. Do not scale air or vacuum (unless explicity requested)
860 iter = m_scalingMap.find("ALL");
861 if (iter != m_scalingMap.end() && materialName != "std::Air" && materialName != "std::Vacuum") {
862 return iter->second;
863 }
864 }
865
866 // If not found then return -1 to indicate material is not to be scaled.
867 return -1;
868}

◆ getMaterial() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( const std::string & materialName)

Get material. First looks for locally defined material and if not found looks in GeoModel material manager.

Definition at line 98 of file InDetMaterialManager.cxx.

98 {
99 return extraScaledMaterial(materialName, getMaterialInternal(materialName));
100}

◆ getMaterial() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & fractWeights,
double density )

Definition at line 657 of file InDetMaterialManager.cxx.

660 {
661 return extraScaledMaterial(name, getMaterialInternal(name, materialComponents, fracWeight, density));
662}

◆ getMaterial() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( const std::string & origMaterialName,
double density,
const std::string & newName = "" )

Create and get material with a specified density based on an existing material.

If a newName is supplied it creates the new material even if the orginal material has the same density. It however first checks if the material with NewName exists. If no newName is supplied then it checks the density of the existing material. If it is consistent it returns the material. If it is different it creates a material with the string "Modified" added to the name.

Definition at line 208 of file InDetMaterialManager.cxx.

210 {
211 return extraScaledMaterial(origMaterialName, newName,
212 getMaterialInternal(origMaterialName, density, newName));
213}

◆ getMaterialForVolume()

const GeoMaterial * InDetMaterialManager::getMaterialForVolume ( const std::string & materialName,
double volume,
const std::string & newName = "" )

Create and get material with a density calculated to give weight in predefined weight table.

Definition at line 431 of file InDetMaterialManager.cxx.

431 {
432 // Make sure we have a valid volume size.
433 if (volume <= 0) {
434 ATH_MSG_ERROR("Invalid volume : " << volume);
435 return nullptr;
436 }
437
438 // Find if material is in the weight table.
439 // If so we use the information to create a material with the
440 // density calculated from the volume and weight. If a base material
441 // is specified in the weight table, then a new material is made
442 // which is the same as the base material but with the new
443 // density. If no base material is specified then there should be a
444 // material already existing with that name. If the existing material already has the
445 // correct density it is used, otherwise a new material is created
446 // with the string "Modified" added to the material name.
447
448 MaterialWeightMap::const_iterator iter;
449 if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) {
450 const std::string& materialBase = iter->second.name;
451 double weight = iter->second.weight;
452 double density = weight / volume;
453 if (iter->second.linearWeightFlag) {
454 ATH_MSG_ERROR("Material defined by linear weight cannot be created with getMaterialForVolume method: " <<
455 materialName);
456 }
457
458 ATH_MSG_VERBOSE("Found material in weight table - name, base, weight(g), volume(cm3), density(g/cm3): "
459 << materialName << ", "
460 << materialBase << ", "
461 << weight / GeoModelKernelUnits::gram << ", "
462 << volume / Gaudi::Units::cm3 << ", "
463 << density / (Gaudi::Units::g / Gaudi::Units::cm3));
464
465 if (materialBase.empty()) {
466 return getMaterial(materialName, density, newName);
467 } else {
468 if (newName.empty()) {
469 return getMaterial(materialBase, density, materialName);
470 } else {
471 return getMaterial(materialBase, density, newName);
472 }
473 }
474 } else {
475 // If not in the weight table we just return the material.
476 // This is not an error.
477 ATH_MSG_VERBOSE("Material not in weight table, using standard material: "
478 << materialName
479 << ", volume(cm3) = " << volume / Gaudi::Units::cm3);
480 return getMaterial(materialName);
481 }
482}
#define ATH_MSG_VERBOSE(x)

◆ getMaterialForVolumeLength() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & materialName,
double volume,
double length,
const std::string & newName = "" )

Definition at line 485 of file InDetMaterialManager.cxx.

486 {
487 // In the case there is no material composition table (MaterialCompositionMap) and no linear weights are used this
488 // will
489 // behave the same way as getMaterialForVolume.
490 // If the material is in the MaterialCompositionMap it will build a material using the components
491 // from that table. If any components are defined as a linear weight the length is used to calculate the
492 // weight (ie linear weight * length).
493
494
495 std::string name;
496 if (newName.empty()) {
497 name = materialName;
498 } else {
499 name = newName;
500 }
501
502 // Make sure we have a valid volume size.
503 if (volume <= 0 || length <= 0) {
504 ATH_MSG_ERROR("Invalid volume or length : " << volume << ", " << length);
505 return nullptr;
506 }
507
508 // First look in the predefinded collections
509 std::pair<MaterialCompositionMap::const_iterator, MaterialCompositionMap::const_iterator> iterRange;
510 iterRange = m_matCompositionMap.equal_range(materialName);
511 if (iterRange.first != m_matCompositionMap.end()) {
512 ATH_MSG_VERBOSE("Found material in material composition table:" << materialName);
513
514 std::vector<double> factors;
515 std::vector<std::string> components;
516 for (MaterialCompositionMap::const_iterator iter = iterRange.first; iter != iterRange.second; ++iter) {
517 double factorTmp = iter->second.factor;
518 if (iter->second.actualLength > 0) factorTmp *= iter->second.actualLength / length;
519 factors.push_back(factorTmp);
520 components.push_back(iter->second.name);
521 }
522 return getMaterialForVolumeLength(name, components, factors, volume, length);
523 }
524
525 // Next look in weight table
526 MaterialWeightMap::const_iterator iter;
527 if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) {
528 const std::string& materialBase = iter->second.name;
529 double weight = iter->second.weight;
530 double density = weight / volume;
531 if (iter->second.linearWeightFlag) weight *= length;
532
533 if (materialBase.empty()) {
534 return getMaterial(materialName, density, newName);
535 } else {
536 return getMaterial(materialBase, density, name);
537 }
538 } else {
539 // Otherwise we just return the material.
540 // This is not an error.
541 ATH_MSG_VERBOSE("Material not in weight table, using standard material: "
542 << materialName
543 << ", volume(cm3) = " << volume / Gaudi::Units::cm3);
544 return getMaterial(materialName);
545 }
546}
double length(const pvec &v)
const GeoMaterial * getMaterialForVolumeLength(const std::string &materialName, double volume, double length, const std::string &newName="")

◆ getMaterialForVolumeLength() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & name,
const std::string & materialComponent,
double factor,
double volume,
double length )

Definition at line 549 of file InDetMaterialManager.cxx.

553 {
554 std::vector<std::string> tmpMaterialComponents(1, materialComponent);
555 std::vector<double> tmpFactors(1, factor);
556 return getMaterialForVolumeLength(name, tmpMaterialComponents, tmpFactors, volume, length);
557}

◆ getMaterialForVolumeLength() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & factors,
double volume,
double length )

Definition at line 560 of file InDetMaterialManager.cxx.

564 {
565 // Make sure we have a valid volume size.
566 if (volume <= 0 || length <= 0) {
567 ATH_MSG_ERROR("Invalid volume or length : " << volume << ", " << length);
568 return nullptr;
569 }
570
571 if (!factors.empty() && factors.size() < materialComponents.size()) {
572 ATH_MSG_WARNING("getMaterialForVolumeLength: factor vector size too small. Setting remaining factors to 1.");
573 }
574
575 std::vector<std::string> baseMaterials;
576 std::vector<double> fracWeight;
577 baseMaterials.reserve(materialComponents.size());
578 fracWeight.reserve(materialComponents.size());
579
580 double totWeight = 0;
581 for (unsigned int iComp = 0; iComp < materialComponents.size(); ++iComp) {
582 const std::string& materialName = materialComponents[iComp];
583
584 // First search in MaterialWeightMap
585 MaterialWeightMap::const_iterator iter;
586 if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) {
587 const std::string& materialBase = iter->second.name;
588 double weight = iter->second.weight;
589
590 if (iComp < factors.size()) {
591 weight *= factors[iComp];
592 }
593 ATH_MSG_DEBUG("Material " << materialName
594 << " found in weight table, weight " << iter->second.weight / GeoModelKernelUnits::gram
595 << " factor " << factors[iComp]
596 << " w*fac*len " << weight * length / GeoModelKernelUnits::gram
597 << " basMat " << materialBase
598 << " linear? " << iter->second.linearWeightFlag);
599
600 if (iter->second.linearWeightFlag) weight *= length;
601 if (materialBase.empty()) {
602 // If no base material then name should refer to an already defined material
603 baseMaterials.push_back(materialName);
604 } else {
605 baseMaterials.push_back(materialBase);
606 }
607 fracWeight.push_back(weight); // Will be normalized later.
608 totWeight += weight;
609 } else {
610 // If not in the weight table we look for a regular material.
611 // I don't think this would normally be intentional so we give a warning message.
612 /*
613 if (msgLvl(MSG::WARNING))
614 msg(MSG::WARNING)
615 << "Component material not in weight table, using standard material: "
616 << materialName << " with weight= "
617 << factors.at(iComp) * length
618 << endmsg;
619 const GeoMaterial * material = getMaterialInternal(materialName);
620 */
621
622 // In this case the factor should correspond to the linear weight
623 double weight = factors.at(iComp) * length * GeoModelKernelUnits::gram;
624
625 // If material not found, will get error message when attempting to make the material. So carry on here.
626 baseMaterials.push_back(materialName);
627 fracWeight.push_back(weight);
628 totWeight += weight;
629 }
630 }
631
632 if (msgLvl(MSG::VERBOSE)) {
633 msg(MSG::VERBOSE) << "Creating material from multiple components: " << name << endmsg;
634 for (unsigned int i = 0; i < materialComponents.size(); ++i) {
635 msg(MSG::VERBOSE) << " Component " << i << ": Name = " << baseMaterials[i]
636 << " Weight(g) = " << fracWeight[i] / Gaudi::Units::g << endmsg;
637 }
638 }
639 if (close_to_zero(totWeight)){
640 ATH_MSG_ERROR("totWeight is zero in InDetMaterialManager::getMaterialForVolumeLength");
641 return nullptr;
642 }
643 for (unsigned int i = 0; i < fracWeight.size(); ++i) {
644 fracWeight[i] /= totWeight;
645 }
646 if (close_to_zero(volume)){
647 ATH_MSG_ERROR("volume is zero in InDetMaterialManager::getMaterialForVolumeLength");
648 return nullptr;
649 }
650 double density = totWeight / volume;
651
652 return getMaterial(name, baseMaterials, fracWeight, density);
653}
#define endmsg
MsgStream & msg() const
The standard message stream.
bool msgLvl(const MSG::Level lvl) const
Test the output level.

◆ getMaterialInternal() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( const std::string & materialName)
private

Definition at line 108 of file InDetMaterialManager.cxx.

108 {
109 // First check local store of materials. If not found then get it from the GeoModel
110 // manager.
111 const GeoMaterial* material = getAdditionalMaterial(materialName);
112
113 if (!material) {
114 if(!m_materialManager) {
115 std::string errorMessage("Null pointer to Stored Material Manager!");
116 ATH_MSG_FATAL(errorMessage);
117 throw std::runtime_error(errorMessage);
118 }
119 // This prints error message if not found.
120 material = m_materialManager->getMaterial(materialName);
121 }
122 return material;
123}

◆ getMaterialInternal() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & fractWeights,
double density )
private

Definition at line 665 of file InDetMaterialManager.cxx.

668 {
669 const GeoMaterial* newMaterial = nullptr;
670
671 // First see if we already have the material
672 const GeoMaterial* material = getAdditionalMaterial(name);
673
674 if (material) {
675 if (!compareDensity(material->getDensity(), density)) {
676 ATH_MSG_WARNING("Density is not consistent for material " << name);
677 }
678 newMaterial = material;
679 } else {
680 GeoMaterial* newMaterialTmp = new GeoMaterial(name, density);
681 for (unsigned int i = 0; i < materialComponents.size(); i++) {
682 const GeoMaterial* origMaterial = getMaterialInternal(materialComponents[i]);
683 if (origMaterial) {
684 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), fracWeight[i]);
685 } else {
686 ATH_MSG_ERROR("Material component missing " << materialComponents[i]);
687 }
688 }
689 addMaterial(newMaterialTmp);
690 newMaterial = newMaterialTmp;
691 }
692 return newMaterial;
693}
bool compareDensity(double d1, double d2) const

◆ getMaterialInternal() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( const std::string & origMaterialName,
double density,
const std::string & newName = "" )
private

Definition at line 216 of file InDetMaterialManager.cxx.

218 {
219 std::string newName2 = newName;
220 bool newNameProvided = !newName2.empty();
221 if (!newNameProvided) {
222 newName2 = origMaterialName + "Modified";
223 }
224
225 const GeoMaterial* newMaterial = nullptr;
226
227 // First see if we already have the modified material
228 const GeoMaterial* material = getAdditionalMaterial(newName2);
229 if (material) {
230 if (!compareDensity(material->getDensity(), density)) {
231 ATH_MSG_WARNING("Density is not consistent for material " << newName2
232 << " " << material->getDensity() / (GeoModelKernelUnits::gram / Gaudi::Units::cm3)
233 << " / " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
234 }
235 newMaterial = material;
236 } else {
237 const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName);
238 newMaterial = origMaterial;
239 if (origMaterial) {
240 // If no new name was provided we check if the density is compatible
241 // and if so we return the original material.
242 if (newNameProvided || !compareDensity(origMaterial->getDensity(), density)) {
243 // create new material
244 GeoMaterial* newMaterialTmp = new GeoMaterial(newName2, density);
245 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.);
246 addMaterial(newMaterialTmp);
247 newMaterial = newMaterialTmp;
248 }
249 }
250 }
251 return newMaterial;
252}

◆ getMaterialScaled()

const GeoMaterial * InDetMaterialManager::getMaterialScaled ( const std::string & origMaterialName,
double scaleFactor,
const std::string & newName = "" )

Definition at line 255 of file InDetMaterialManager.cxx.

257 {
258 return extraScaledMaterial(origMaterialName, newName,
259 getMaterialScaledInternal(origMaterialName, scaleFactor, newName));
260}
const GeoMaterial * getMaterialScaledInternal(const std::string &origMaterialName, double scaleFactor, const std::string &newName="")

◆ getMaterialScaledInternal()

const GeoMaterial * InDetMaterialManager::getMaterialScaledInternal ( const std::string & origMaterialName,
double scaleFactor,
const std::string & newName = "" )
private

Definition at line 263 of file InDetMaterialManager.cxx.

265 {
266 // Don't allow large scale factors
267 if (scaleFactor > 1000 || scaleFactor < 0.001) {
268 ATH_MSG_ERROR("Scale factor must be between 0.001 and 1000.");
269 return nullptr;
270 }
271
272 const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName);
273
274 // If scalefactor is 1 and no new name is requested
275 // then just return the orginal material
276 if (newName.empty() && scaleFactor == 1.) return origMaterial;
277
278 const GeoMaterial* newMaterial = nullptr;
279
280 if (origMaterial) {
281 double density = origMaterial->getDensity() * scaleFactor;
282 std::string newName2 = newName;
283 if (newName2.empty()) {
284 // Create name using the scale factor.
285 int scaleInt = static_cast<int>(scaleFactor * 10000);
286 int scale1 = scaleInt / 10000;
287 int scale2 = scaleInt % 10000;
288
289 std::ostringstream os;
290 os << origMaterialName << scale1 << "_" << std::setw(4) << std::setfill('0') << scale2;
291 newName2 = os.str();
292 }
293
294 newMaterial = getMaterialInternal(origMaterialName, density, newName2);
295 }
296
297 return newMaterial;
298}
#define scale2
#define scale1

◆ hasMaterial()

bool InDetMaterialManager::hasMaterial ( const std::string & materialName) const

Definition at line 103 of file InDetMaterialManager.cxx.

103 {
104 return m_weightMap.find(materialName) != m_weightMap.end();
105}

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ retrieveManager()

StoredMaterialManager * InDetMaterialManager::retrieveManager ( const StoreGateSvc * detStore)
inlineprivate

Definition at line 83 of file InDetMaterialManager.cxx.

83 {
84 return detStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
85}
T * tryRetrieve() const
Variant of the above which doesn't print a warning message.

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_extraFunctionality

bool InDetMaterialManager::m_extraFunctionality
private

Definition at line 224 of file InDetMaterialManager.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_managerName

std::string InDetMaterialManager::m_managerName
private

Definition at line 209 of file InDetMaterialManager.h.

◆ m_matCompositionMap

MaterialCompositionMap InDetMaterialManager::m_matCompositionMap
private

Definition at line 218 of file InDetMaterialManager.h.

◆ m_materialManager

StoredMaterialManager* InDetMaterialManager::m_materialManager
private

Definition at line 208 of file InDetMaterialManager.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_scalingMap

ExtraScaleFactorMap InDetMaterialManager::m_scalingMap
private

Definition at line 221 of file InDetMaterialManager.h.

◆ m_store

MaterialStore InDetMaterialManager::m_store
private

Definition at line 212 of file InDetMaterialManager.h.

◆ m_weightMap

MaterialWeightMap InDetMaterialManager::m_weightMap
private

Definition at line 215 of file InDetMaterialManager.h.


The documentation for this class was generated from the following files: