diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h index 2d5ed83d502d3856812688cd62a5e4bf49b64eeb..afa6f59d3d6b851fd5d8126e2d5d98ee6dc790db 100644 --- a/DDCore/include/DD4hep/Segmentations.h +++ b/DDCore/include/DD4hep/Segmentations.h @@ -6,7 +6,6 @@ // Author : M.Frank // //==================================================================== - #ifndef DD4HEP_GEOMETRY_SEGMENTATIONS_H #define DD4HEP_GEOMETRY_SEGMENTATIONS_H @@ -15,6 +14,7 @@ // C/C++ include files #include <cmath> +#include <vector> /* * DD4hep namespace declaration @@ -26,7 +26,7 @@ namespace DD4hep { */ namespace Geometry { - /** @class Segmentation Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class Segmentation Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -34,7 +34,7 @@ namespace DD4hep { struct Segmentation : public Ref_t { public: enum { REGULAR=0, EXTENDED=1 }; - + struct Object { /// Magic word to check object integrity unsigned long magic; @@ -110,14 +110,38 @@ namespace DD4hep { template <class T> T* extension() const { return (T*)i_extension(typeid(T)); } /// Access extension element by the type template <class T> T* extensionUnchecked() const { return (T*)_data().data.extension.ptr;} - + /// Compute the coordinate in one dimension given a eauidistant bin value. static double binCenter(int bin, double width) { return (double(bin) + .5) * width; } /// Compute the equidistant bin given a coordinate in one dimension. static int bin(double value, double width) { return int(floor(value/width)); } }; - /** @class ProjectiveCylinder Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class SegmentationParams Segmentations.h DD4hep/Segmentations.h + * + * @author M.Frank + * @version 1.0 + */ + struct SegmentationParams : public Ref_t { + public: + /// Segmentation parameter definition + typedef std::pair<std::string,double> Parameter; + /// Segmentation parameter container definition + typedef std::vector<Parameter> Parameters; + /// Object type + typedef Segmentation::Object Object; + + /// Constructor to be used when reading the already parsed object + SegmentationParams(const Segmentation& e) : Ref_t(e) {} + /// Accessor to ata structure + Object& _data() const { return *data<Object>(); } + /// Segmentation type + const std::string type() const; + /// Access to the parameters + Parameters parameters() const; + }; + + /** @class ProjectiveCylinder Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -137,7 +161,7 @@ namespace DD4hep { void setPhiBins(int value); }; - /** @class NonProjectiveCylinder Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class NonProjectiveCylinder Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -157,7 +181,7 @@ namespace DD4hep { void setPhiBinSize(double value); }; - /** @class ProjectiveZPlane Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class ProjectiveZPlane Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -177,7 +201,7 @@ namespace DD4hep { void setPhiBins(int value); }; - /** @class GridXY Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class GridXY Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -201,7 +225,7 @@ namespace DD4hep { double getGridSizeY()const; }; - /** @class GridXYZ Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class GridXYZ Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -217,7 +241,7 @@ namespace DD4hep { void setGridSizeZ(double value); }; - /** @class CartesianGridXY Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class CartesianGridXY Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 @@ -229,7 +253,7 @@ namespace DD4hep { CartesianGridXY() : GridXY("cartesian_grid_xy") {} }; - /** @class GlobalGridXY Segmentations.h DD4hep/lcdd/Segmentations.h + /** @class GlobalGridXY Segmentations.h DD4hep/Segmentations.h * * @author M.Frank * @version 1.0 diff --git a/DDCore/src/Segementations.cpp b/DDCore/src/Segementations.cpp index 047401cd28d5180485921be7160515a029605793..416565416e2074dcc7dd67f45f8191501e150bc8 100644 --- a/DDCore/src/Segementations.cpp +++ b/DDCore/src/Segementations.cpp @@ -39,6 +39,7 @@ bool Segmentation::useForHitPosition() const { return _data().useForHitPosition != 0; } +/// Segmentation type const string Segmentation::type() const { return m_element->GetTitle(); } @@ -70,8 +71,50 @@ void* Segmentation::i_extension(const type_info& info) const { throw runtime_error("extension: The segmentation object is not valid!"); } -ProjectiveCylinder::ProjectiveCylinder() -: Segmentation("projective_cylinder") {} +/// Segmentation type +const string SegmentationParams::type() const { + return m_element->GetTitle(); +} + +/// Access to the parameters +SegmentationParams::Parameters SegmentationParams::parameters() const { + const string& typ = type(); + const Object& obj = _data(); + const Object::Data& data = obj.data; + Parameters params; + if ( typ == "projective_cylinder" ) { + params.push_back(make_pair("ntheta",data.cylindrical_binning.ntheta)); + params.push_back(make_pair("nphi",data.cylindrical_binning.nphi)); + } + else if ( typ == "nonprojective_cylinder" ) { + params.push_back(make_pair("grid_size_z",data.cylindrical_grid.grid_size_phi)); + params.push_back(make_pair("grid_size_phi",data.cylindrical_grid.grid_size_phi)); + params.push_back(make_pair("lunit",_toDouble("mm"))); + } + else if ( typ == "projective_zplane" ) { + params.push_back(make_pair("ntheta",data.cylindrical_binning.ntheta)); + params.push_back(make_pair("nphi",data.cylindrical_binning.nphi)); + } + else if ( typ == "grid_xy" || typ == "global_grid_xy" ) { + params.push_back(make_pair("grid_size_x",data.cartesian_grid.grid_size_x)); + params.push_back(make_pair("grid_size_y",data.cartesian_grid.grid_size_y)); + params.push_back(make_pair("lunit",_toDouble("mm"))); + } + else if ( typ == "grid_xyz" || typ == "global_grid_xyz" ) { + params.push_back(make_pair("grid_size_x",data.cartesian_grid.grid_size_x)); + params.push_back(make_pair("grid_size_y",data.cartesian_grid.grid_size_y)); + params.push_back(make_pair("grid_size_z",data.cartesian_grid.grid_size_z)); + params.push_back(make_pair("lunit",_toDouble("mm"))); + } + else { + throw runtime_error("The segmentation type "+typ+" is not supported by DD4hep."); + } + return params; +} + +ProjectiveCylinder::ProjectiveCylinder() : Segmentation("projective_cylinder") +{ +} /// Accessors: get number of bins in theta int ProjectiveCylinder::thetaBins() const { diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp index 0c206bd90da9041506ee9f5d101e6c651b4c6d4e..99dc9b3d60d51e9f93ca08b92bf6578502558bbe 100644 --- a/DDCore/src/plugins/LCDDConverter.cpp +++ b/DDCore/src/plugins/LCDDConverter.cpp @@ -10,6 +10,7 @@ // Framework includes #include "DD4hep/Volumes.h" #include "DD4hep/FieldTypes.h" +#include "DD4hep/Segmentations.h" #include "XML/DocumentHandler.h" #include "LCDDConverter.h" @@ -402,10 +403,10 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c xml_h right = handleSolid(rs->GetName(),rs); xml_h first(0), second(0); if ( !left ) { - throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:"+name); + throw runtime_error("G4Converter: No left LCDD Solid present for composite shape:"+name); } if ( !right ) { - throw runtime_error("G4Converter: No right Geant4 Solid present for composite shape:"+name); + throw runtime_error("G4Converter: No right LCDD Solid present for composite shape:"+name); } if ( oper == TGeoBoolNode::kGeoSubtraction ) @@ -539,9 +540,9 @@ xml_h LCDDConverter::handleVolume(const string& name, const TGeoVolume* volume) xml_ref_t sol = handleSolid(s->GetName(),s); if ( !sol ) - throw runtime_error("G4Converter: No Geant4 Solid present for volume:"+n); + throw runtime_error("G4Converter: No LCDD Solid present for volume:"+n); else if ( !m && v->IsA() != TGeoVolumeAssembly::Class() ) - throw runtime_error("G4Converter: No Geant4 material present for volume:"+n); + throw runtime_error("G4Converter: No LCDD material present for volume:"+n); geo.checkVolume(name,volume); geo.doc_structure.append(vol=xml_elt_t(geo.doc,_U(volume))); @@ -687,7 +688,7 @@ xml_h LCDDConverter::handlePlacement(const string& name, const TGeoNode* node) c return place; } -/// Convert the geometry type region into the corresponding Geant4 object(s). +/// Convert the geometry type region into the corresponding LCDD object(s). xml_h LCDDConverter::handleRegion(const std::string& name, const TNamed* region) const { GeometryInfo& geo = data(); xml_h reg = geo.xmlRegions[region]; @@ -704,7 +705,7 @@ xml_h LCDDConverter::handleRegion(const std::string& name, const TNamed* region) return reg; } -/// Convert the geometry type LimitSet into the corresponding Geant4 object(s) +/// Convert the geometry type LimitSet into the corresponding LCDD object(s) xml_h LCDDConverter::handleLimitSet(const std::string& name, const TNamed* limitset) const { GeometryInfo& geo = data(); xml_h xml = geo.xmlLimits[limitset]; @@ -727,7 +728,33 @@ xml_h LCDDConverter::handleLimitSet(const std::string& name, const TNamed* limit return xml; } -/// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s). +/// Convert the segmentation of a SensitiveDetector into the corresponding LCDD object +xml_h LCDDConverter::handleSegmentation(Segmentation seg) const { + xml_h xml; + if ( seg.isValid() ) { + typedef SegmentationParams::Parameters _P; + string typ = seg.type(); + SegmentationParams par(seg); + _P p = par.parameters(); + xml = xml_elt_t(data().doc,Unicode(typ)); + for(_P::const_iterator i=p.begin(); i != p.end(); ++i) { + const _P::value_type& v=*i; + if ( v.first == "lunit" ) { + string val = v.second == _toDouble("mm") ? "mm" : + v.second == _toDouble("cm") ? "cm" : + v.second == _toDouble("m") ? "m" : + v.second == _toDouble("micron") ? "micron" : + v.second == _toDouble("nanometer") ? "namometer" : "??"; + xml.setAttr(Unicode(v.first),Unicode(val)); + continue; + } + xml.setAttr(Unicode(v.first),v.second); + } + } + return xml; +} + +/// Convert the geometry type SensitiveDetector into the corresponding LCDD object(s). xml_h LCDDConverter::handleSensitive(const string& name, const TNamed* sens_det) const { GeometryInfo& geo = data(); xml_h sensdet = geo.xmlSensDets[sens_det]; @@ -744,6 +771,8 @@ xml_h LCDDConverter::handleSensitive(const string& name, const TNamed* sens_det) if ( ro.isValid() ) { xml_ref_t ref = handleIdSpec(ro.idSpec().name(),ro.idSpec().ptr()); sensdet.setRef(_U(idspecref),ref.name()); + xml_h seg = handleSegmentation(ro.segmentation()); + if ( seg ) sensdet.append(seg); } geo.xmlSensDets[sens_det] = sensdet; } @@ -777,7 +806,7 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec return id; } -/// Convert the geometry visualisation attributes to the corresponding Geant4 object(s). +/// Convert the geometry visualisation attributes to the corresponding LCDD object(s). xml_h LCDDConverter::handleVis(const string& name, const TNamed* v) const { GeometryInfo& geo = data(); xml_h vis = geo.xmlVis[v]; @@ -869,7 +898,7 @@ void LCDDConverter::handleProperties(LCDD::Properties& prp) const { if ( result != 1 ) { throw runtime_error("Failed to invoke the plugin "+tag+" of type "+type); } - cout << "+++++ Executed Successfully Geant4 setup module *" << type << "* ." << endl; + cout << "+++++ Executed Successfully LCDD setup module *" << type << "* ." << endl; } } @@ -948,7 +977,7 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { geo.doc_setup.setAttr(_U(name),Unicode("Default")); geo.doc_setup.setAttr(_U(version),Unicode("1.0")); - // Ensure that all required materials are present in the Geant4 material table + // Ensure that all required materials are present in the LCDD material table #if 0 const LCDD::HandleMap& mat = lcdd.materials(); for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i) @@ -1057,7 +1086,7 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { geo.doc_setup.setAttr(_U(name),Unicode("Default")); geo.doc_setup.setAttr(_U(version),Unicode("1.0")); - // Ensure that all required materials are present in the Geant4 material table + // Ensure that all required materials are present in the LCDD material table #if 0 const LCDD::HandleMap& mat = lcdd.materials(); for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i) diff --git a/DDCore/src/plugins/LCDDConverter.h b/DDCore/src/plugins/LCDDConverter.h index af9ffc646bcd5d4bebbdff86a11fc06e0d3abab8..1ae298d669ed229d7b24e5e57e5259620229d9e1 100644 --- a/DDCore/src/plugins/LCDDConverter.h +++ b/DDCore/src/plugins/LCDDConverter.h @@ -162,6 +162,9 @@ namespace DD4hep { /// Convert the geometry type SensitiveDetector into the corresponding Xml object(s). virtual xml_h handleSensitive(const std::string& name, const TNamed* sens_det) const; + /// Convert the segmentation of a SensitiveDetector into the corresponding LCDD object + virtual xml_h handleSegmentation(Segmentation seg) const; + /// Convert the Position into the corresponding Xml object(s). virtual xml_h handlePosition(const std::string& name, const TGeoMatrix* trafo) const;