diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MDTProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MDTProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..1c36635a169277aa90182a073bf522e0a6201bc4 --- /dev/null +++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MDTProcessor.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEO_MODEL_XML_MDT_PROCESSOR_H +#define GEO_MODEL_XML_MDT_PROCESSOR_H +#include <xercesc/util/XercesDefs.hpp> +// +// Processor for mdt tags. This is a shortcut to create MDT mattresses at once, rather than going the full XML way +// +#include <string> +#include <map> + +#include "GeoModelXml/ElementProcessor.h" +class GmxUtil; +class GeoNameTag; +class GeoLogVol; +class GeoPhysVol; + +class MDTProcessor: public ElementProcessor { +public: + typedef struct { + GeoNameTag *name; + int id; + GeoLogVol *logVol; + bool alignable; + } MDTStore; + void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd); +private: + std::map<std::string, MDTStore> m_map; + GeoPhysVol* BuildExampleVolume(std::string name); +}; + +#endif // MDT_PROCESSOR_H diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx index 80fa1e59ada0a94743702b89fa9e01231e2ea9ef..c6a6736bcd58943748eb83314adce64fba913121 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx @@ -32,189 +32,189 @@ using namespace std; using namespace xercesc; void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) { -GeoLogVol *lv; -GeoNameTag *physVolName; + GeoLogVol *lv; + GeoNameTag *physVolName; - gmxUtil.positionIndex.incrementLevel(); + gmxUtil.positionIndex.incrementLevel(); - XMLCh * name_tmp = XMLString::transcode("name"); - char *name2release = XMLString::transcode(element->getAttribute(name_tmp)); - string name(name2release); - XMLString::release(&name2release); - XMLString::release(&name_tmp); + XMLCh * name_tmp = XMLString::transcode("name"); + char *name2release = XMLString::transcode(element->getAttribute(name_tmp)); + string name(name2release); + XMLString::release(&name2release); + XMLString::release(&name_tmp); // // Look for the logvol in the map; if not yet there, add it // - map<string, LogVolStore>::iterator entry; - if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item + map<string, LogVolStore>::iterator entry; + if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item // // Name // - m_map[name] = LogVolStore(); - LogVolStore *store = &m_map[name]; - physVolName = new GeoNameTag(name); - store->name = physVolName; - store->id = 0; + m_map[name] = LogVolStore(); + LogVolStore *store = &m_map[name]; + physVolName = new GeoNameTag(name); + store->name = physVolName; + store->id = 0; // // Get the shape. // - DOMDocument *doc = element->getOwnerDocument(); - XMLCh * shape_tmp = XMLString::transcode("shape"); - const XMLCh *shape = element->getAttribute(shape_tmp); - DOMElement *refShape = doc->getElementById(shape); - // Check it is a shape... its parent should be a <shapes>. DTD cannot do this for us. - DOMNode *parent = refShape->getParentNode(); - if (XMLString::compareIString(parent->getNodeName(), XMLString::transcode("shapes")) != 0) { + DOMDocument *doc = element->getOwnerDocument(); + XMLCh * shape_tmp = XMLString::transcode("shape"); + const XMLCh *shape = element->getAttribute(shape_tmp); + DOMElement *refShape = doc->getElementById(shape); + // Check it is a shape... its parent should be a <shapes>. DTD cannot do this for us. + DOMNode *parent = refShape->getParentNode(); + if (XMLString::compareIString(parent->getNodeName(), XMLString::transcode("shapes")) != 0) { - msglog << MSG::FATAL << "Processing logvol " << name << + msglog << MSG::FATAL << "Processing logvol " << name << ". Error in gmx file. An IDREF for a logvol shape did not refer to a shape.\n" << "Shape ref was " << shape << "; exiting" << endmsg; - exit (1); // Need to improve... - } + exit (1); // Need to improve... + } // // What sort of shape? // - name2release = XMLString::transcode(refShape->getNodeName()); - string shapeType(name2release); - XMLString::release(&name2release); - XMLString::release(&shape_tmp); + name2release = XMLString::transcode(refShape->getNodeName()); + string shapeType(name2release); + XMLString::release(&name2release); + XMLString::release(&shape_tmp); - GeoShape *s = (GeoShape *) gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil); + GeoShape *s = (GeoShape *) gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil); // // Get the material // - XMLCh * material_tmp = XMLString::transcode("material"); - const XMLCh *material = element->getAttribute(material_tmp); - DOMElement *refMaterial = doc->getElementById(material); - // Check it is a material... its parent should be a <materials>. DTD cannot do this for us. - parent = refMaterial->getParentNode(); - XMLCh * materials_tmp = XMLString::transcode("materials"); - if (XMLString::compareIString(parent->getNodeName(), materials_tmp) != 0) { - msglog << MSG::FATAL << "Processing logvol " << name << + XMLCh * material_tmp = XMLString::transcode("material"); + const XMLCh *material = element->getAttribute(material_tmp); + DOMElement *refMaterial = doc->getElementById(material); + // Check it is a material... its parent should be a <materials>. DTD cannot do this for us. + parent = refMaterial->getParentNode(); + XMLCh * materials_tmp = XMLString::transcode("materials"); + if (XMLString::compareIString(parent->getNodeName(), materials_tmp) != 0) { + msglog << MSG::FATAL << "Processing logvol " << name << ". Error in gmx file. An IDREF for a logvol material did not refer to a material.\n" << "Material ref was " << material << "; exiting" << endmsg; - exit (1); // Need to improve... - } - std::string nam_mat=XMLString::transcode(material); + exit (1); // Need to improve... + } + std::string nam_mat=XMLString::transcode(material); - GeoMaterial* m=0; + GeoMaterial* m=0; - if (gmxUtil.matManager) - { - if (!gmxUtil.matManager->isMaterialDefined(nam_mat)) + if (gmxUtil.matManager) { - GeoMaterial* tempMat=(GeoMaterial *) gmxUtil.tagHandler.material.process(refMaterial, gmxUtil); - // we let GMX create the material and store it in the MM + if (!gmxUtil.matManager->isMaterialDefined(nam_mat)) + { + GeoMaterial* tempMat=(GeoMaterial *) gmxUtil.tagHandler.material.process(refMaterial, gmxUtil); + // we let GMX create the material and store it in the MM - gmxUtil.matManager->addMaterial(tempMat); + gmxUtil.matManager->addMaterial(tempMat); + } + m=const_cast<GeoMaterial*>(gmxUtil.matManager->getMaterial(nam_mat)); } - m=const_cast<GeoMaterial*>(gmxUtil.matManager->getMaterial(nam_mat)); - } - else - m=(GeoMaterial *) gmxUtil.tagHandler.material.process(refMaterial, gmxUtil); + else + m=(GeoMaterial *) gmxUtil.tagHandler.material.process(refMaterial, gmxUtil); // // Make the LogVol and add it to the map ready for next time // - lv = new GeoLogVol(name, s, m); - store->logVol = lv; + lv = new GeoLogVol(name, s, m); + store->logVol = lv; - XMLString::release(&material_tmp); - XMLString::release(&materials_tmp); -} -else { // Already in the registry; use it. - physVolName = entry->second.name; - lv = entry->second.logVol; -} + XMLString::release(&material_tmp); + XMLString::release(&materials_tmp); + } + else { // Already in the registry; use it. + physVolName = entry->second.name; + lv = entry->second.logVol; + } // // Process the logvol children (side effect: sets formulae for indexes before calculating them) // - GeoNodeList childrenAdd; - for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) { - if (child->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMElement *el = dynamic_cast<DOMElement *> (child); - name2release = XMLString::transcode(el->getNodeName()); - string name(name2release); - XMLString::release(&name2release); - gmxUtil.processorRegistry.find(name)->process(el, gmxUtil, childrenAdd); - } + GeoNodeList childrenAdd; + for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) { + if (child->getNodeType() == DOMNode::ELEMENT_NODE) { + DOMElement *el = dynamic_cast<DOMElement *> (child); + name2release = XMLString::transcode(el->getNodeName()); + string name(name2release); + XMLString::release(&name2release); + gmxUtil.processorRegistry.find(name)->process(el, gmxUtil, childrenAdd); } + } // // Make a list of things to be added // - toAdd.push_back(physVolName); - XMLCh * sensitive_tmp = XMLString::transcode("sensitive"); - bool sensitive = element->hasAttribute(sensitive_tmp); - int sensId = 0; - //std::vector<int> extraSensIds;//extra Identfiers to be used in case we split this volume into multiple DetectorElements - map<string, int> index; - //map<string, int> updatedIndex;//extra indices to be used in case we split this volume - if (sensitive) { - gmxUtil.positionIndex.setCopyNo(m_map[name].id++); - gmxUtil.positionIndex.indices(index, gmxUtil.eval); - sensId = gmxUtil.gmxInterface()->sensorId(index); - // toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number - toAdd.push_back(new GeoIdentifierTag(sensId)); - } - else { - toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number - gmxUtil.positionIndex.setCopyNo(m_map[name].id++); + toAdd.push_back(physVolName); + XMLCh * sensitive_tmp = XMLString::transcode("sensitive"); + bool sensitive = element->hasAttribute(sensitive_tmp); + int sensId = 0; + //std::vector<int> extraSensIds;//extra Identfiers to be used in case we split this volume into multiple DetectorElements + map<string, int> index; + //map<string, int> updatedIndex;//extra indices to be used in case we split this volume + if (sensitive) { + gmxUtil.positionIndex.setCopyNo(m_map[name].id++); + gmxUtil.positionIndex.indices(index, gmxUtil.eval); + sensId = gmxUtil.gmxInterface()->sensorId(index); + // toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number + toAdd.push_back(new GeoIdentifierTag(sensId)); + } + else { + toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number + gmxUtil.positionIndex.setCopyNo(m_map[name].id++); + } + XMLString::release(&sensitive_tmp); + // + // Make a new PhysVol and add everything to it, then add it to the list of things for my caller to add + // + XMLCh * alignable_tmp = XMLString::transcode("alignable"); + char *toRelease = XMLString::transcode(element->getAttribute(alignable_tmp)); + string alignable(toRelease); + XMLString::release(&toRelease); + XMLString::release(&alignable_tmp); + if (sensitive || (alignable.compare(string("true")) == 0)) { + GeoFullPhysVol *pv = new GeoFullPhysVol(lv); + for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) { + pv->add(*node); } - XMLString::release(&sensitive_tmp); + toAdd.push_back(pv); // NB: the *PV is third item added, so reference as toAdd[2]. // - // Make a new PhysVol and add everything to it, then add it to the list of things for my caller to add + // Add sensitive volumes to detector manager via GmxInterface // - XMLCh * alignable_tmp = XMLString::transcode("alignable"); - char *toRelease = XMLString::transcode(element->getAttribute(alignable_tmp)); - string alignable(toRelease); - XMLString::release(&toRelease); - XMLString::release(&alignable_tmp); - if (sensitive || (alignable.compare(string("true")) == 0)) { - GeoFullPhysVol *pv = new GeoFullPhysVol(lv); - for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) { - pv->add(*node); - } - toAdd.push_back(pv); // NB: the *PV is third item added, so reference as toAdd[2]. - // - // Add sensitive volumes to detector manager via GmxInterface - // - if (sensitive) { - XMLCh * sensitive_tmp = XMLString::transcode("sensitive"); - name2release = XMLString::transcode(element->getAttribute(sensitive_tmp)); - string sensitiveName(name2release); - XMLString::release(&name2release); - XMLString::release(&sensitive_tmp); - //splitting sensors where we would like multiple DetectorElements per GeoVFullPhysVol (e.g.ITk Strips) - XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel"); - bool split = element->hasAttribute(splitLevel_tmp); - char* splitString; - int splitLevel = 1; - if (split) { - splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp)); - splitLevel = gmxUtil.evaluate(splitString); - XMLString::release(&splitString); - XMLString::release(&splitLevel_tmp); - for(int i=0;i<splitLevel;i++){ - std::string field = "eta_module";//eventually specify in Xml the field to split in? - std::pair<std::string,int> extraIndex(field,i); - gmxUtil.gmxInterface()->addSplitSensor(sensitiveName, index,extraIndex, sensId, dynamic_cast<GeoVFullPhysVol *> (pv)); - } - } - else gmxUtil.gmxInterface()->addSensor(sensitiveName, index, sensId, dynamic_cast<GeoVFullPhysVol *> (pv)); - } + if (sensitive) { + XMLCh * sensitive_tmp = XMLString::transcode("sensitive"); + name2release = XMLString::transcode(element->getAttribute(sensitive_tmp)); + string sensitiveName(name2release); + XMLString::release(&name2release); + XMLString::release(&sensitive_tmp); + //splitting sensors where we would like multiple DetectorElements per GeoVFullPhysVol (e.g.ITk Strips) + XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel"); + bool split = element->hasAttribute(splitLevel_tmp); + char* splitString; + int splitLevel = 1; + if (split) { + splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp)); + splitLevel = gmxUtil.evaluate(splitString); + XMLString::release(&splitString); + XMLString::release(&splitLevel_tmp); + for(int i=0;i<splitLevel;i++){ + std::string field = "eta_module";//eventually specify in Xml the field to split in? + std::pair<std::string,int> extraIndex(field,i); + gmxUtil.gmxInterface()->addSplitSensor(sensitiveName, index,extraIndex, sensId, dynamic_cast<GeoVFullPhysVol *> (pv)); + } + } + else gmxUtil.gmxInterface()->addSensor(sensitiveName, index, sensId, dynamic_cast<GeoVFullPhysVol *> (pv)); } - else { - GeoPhysVol *pv = new GeoPhysVol(lv); - for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) { - pv->add(*node); - } - toAdd.push_back(pv); + } + else { + GeoPhysVol *pv = new GeoPhysVol(lv); + for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) { + pv->add(*node); } + toAdd.push_back(pv); + } - gmxUtil.positionIndex.decrementLevel(); - return; + gmxUtil.positionIndex.decrementLevel(); + return; } void LogvolProcessor::zeroId(const xercesc::DOMElement *element) { diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MDTProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MDTProcessor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..77c7845c6504d4b6fbea62f236a28399b38c942a --- /dev/null +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MDTProcessor.cxx @@ -0,0 +1,110 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +// +// Processor for MDT elements +// +// Add name to list. +// Create a physvol using my logvol; add it to list. +// +// +#include "GeoModelXml/MDTProcessor.h" +#include "OutputDirector.h" + +#include <map> + +#include <xercesc/dom/DOM.hpp> +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoCons.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelXml/GmxUtil.h" +#include "GeoModelXml/GeoNodeList.h" +#include "xercesc/util/XMLString.hpp" + +using namespace std; +using namespace xercesc; + +void MDTProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) { +GeoLogVol *lv; +GeoPhysVol* pv; +GeoNameTag *physVolName; + + gmxUtil.positionIndex.incrementLevel(); + + XMLCh * name_tmp = XMLString::transcode("name"); + char *name2release = XMLString::transcode(element->getAttribute(name_tmp)); + string name(name2release); + XMLString::release(&name2release); + XMLString::release(&name_tmp); +// +// Look for the logvol in the map; if not yet there, add it +// + map<string, MDTStore>::iterator entry; + if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item +// +// Name +// + m_map[name] = MDTStore(); + MDTStore *store = &m_map[name]; + physVolName = new GeoNameTag(name); + store->name = physVolName; + store->id = 0; + } +// +// Make the LogVol and add it to the map ready for next time +// +// lv = new GeoLogVol(name, s, m); +// store->logVol = lv; + +else { // Already in the registry; use it. + physVolName = entry->second.name; + lv = entry->second.logVol; +} + + pv=BuildExampleVolume(name); + + toAdd.push_back(pv); + + gmxUtil.positionIndex.decrementLevel(); + return; +} + +#include "GeoModelKernel/Units.h" +#define SYSTEM_OF_UNITS GeoModelKernelUnits + +GeoPhysVol* MDTProcessor::BuildExampleVolume(std::string name) +{ + + // Define the units + #define gr SYSTEM_OF_UNITS::gram + #define mole SYSTEM_OF_UNITS::mole + #define cm3 SYSTEM_OF_UNITS::cm3 + + // Define the chemical elements + + static GeoElement* el_Iron = new GeoElement ("Iron" ,"Fe" , 26.0 , 55.847 *gr/mole); + static GeoElement* el_Carbon = new GeoElement ("Carbon" ,"C" , 6.0 , 12.0107 *gr/mole); + + // Define the materials + + // Steel: Iron + Carbon + GeoMaterial* mat_Steel = new GeoMaterial("Steel", 7.9 *gr/cm3); + mat_Steel->add(el_Iron , 0.98); + mat_Steel->add(el_Carbon, 0.02); + mat_Steel->lock(); + + // A cone +GeoCons* cons = new GeoCons(10.*SYSTEM_OF_UNITS::cm, 20.*SYSTEM_OF_UNITS::cm, 30.*SYSTEM_OF_UNITS::cm, + 40.*SYSTEM_OF_UNITS::cm, 25.*SYSTEM_OF_UNITS::cm, 0.*SYSTEM_OF_UNITS::degree, 270.*SYSTEM_OF_UNITS::degree); + + GeoLogVol* consLog = new GeoLogVol(name, cons, mat_Steel); + GeoPhysVol* consPhys = new GeoPhysVol(consLog); + + return consPhys; + +}