diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h index 834e13e75e21b39bda727deb621630cf99cd2b62..5292907893ace187f8b7710e12bb7d44d4fdd5d9 100644 --- a/DDCore/include/DD4hep/Segmentations.h +++ b/DDCore/include/DD4hep/Segmentations.h @@ -25,36 +25,36 @@ namespace DD4hep { * XML namespace declaration */ namespace Geometry { - + /** @class Segmentation Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank * @version 1.0 */ struct Segmentation : public Ref_t { - public: + public: enum { REGULAR=0, EXTENDED=1 }; - + struct Object { - /// Magic word to check object integrity - unsigned long magic; - /// Segmentation type (REGULAR or EXTENDED) - unsigned char type; - /// Flag to use segmentation for hit positioning + /// Magic word to check object integrity + unsigned long magic; + /// Segmentation type (REGULAR or EXTENDED) + unsigned char type; + /// Flag to use segmentation for hit positioning unsigned char useForHitPosition; - /// Spares to start 16 byte Byte aligned - unsigned char _spare[6]; - + /// Spares to start 16 byte Byte aligned + unsigned char _spare[6]; + union Data { - /// Maximal size and data buffer for specialized user segentations + /// Maximal size and data buffer for specialized user segentations double values[32]; - /// Extension buffer for specialized user segentations, where above values are insufficient - struct Extension { - const std::type_info* info; - void (*destructor)(void*); - void* ptr; - } extension; - /// No the regular structures for default segmentations + /// Extension buffer for specialized user segentations, where above values are insufficient + struct Extension { + const std::type_info* info; + void (*destructor)(void*); + void* ptr; + } extension; + /// No the regular structures for default segmentations struct Cartesian { int nx; int ny; @@ -75,26 +75,26 @@ namespace DD4hep { double grid_size_theta; double grid_size_z; } cylindrical_grid; - + } data; - Object(); - ~Object(); + Object(); + ~Object(); }; - - protected: + + protected: /// Templated destructor function template <typename T> static void _delete(void* ptr) { delete (T*)(ptr); } /// Add an extension object to the detector element void* i_setExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)); /// Access an existing extension object from the detector element void* i_extension(const std::type_info& info) const; - - public: + + public: /// Default constructor Segmentation() : Handle<Implementation>() {} /// Constructor to be used when reading the already parsed object - template <typename Q> Segmentation(const Handle<Q>& e) - : Handle<Implementation>(e){} + template <typename Q> Segmentation(const Handle<Q>& e) + : Handle<Implementation>(e){} /// Constructor to create a new segmentation object (to be called by super class only) Segmentation(const std::string& type); /// Accessor to ata structure @@ -104,19 +104,19 @@ namespace DD4hep { /// Segmentation type const std::string type() const; /// Extend the segmentation object with an arbitrary structure accessible by the type - template<typename IFACE, typename CONCRETE> IFACE* setExtension(CONCRETE* c) + template<typename IFACE, typename CONCRETE> IFACE* setExtension(CONCRETE* c) { return (IFACE*)i_setExtension(dynamic_cast<IFACE*>(c),typeid(IFACE),_delete<IFACE>); } /// Access extension element by the type 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 * * @author M.Frank @@ -136,7 +136,7 @@ namespace DD4hep { /// Accessors: set grid size in Y void setPhiBins(int value); }; - + /** @class NonProjectiveCylinder Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -156,7 +156,7 @@ namespace DD4hep { /// Accessors: set grid size in Y void setPhiBinSize(double value); }; - + /** @class ProjectiveZPlane Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -176,7 +176,7 @@ namespace DD4hep { /// Accessors: set grid size in Y void setPhiBins(int value); }; - + /** @class GridXY Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -200,7 +200,7 @@ namespace DD4hep { /// Accessors: get grid size in Y double getGridSizeY()const; }; - + /** @class GridXYZ Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -216,7 +216,7 @@ namespace DD4hep { /// Accessors: set grid size in Z void setGridSizeZ(double value); }; - + /** @class CartesianGridXY Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -228,7 +228,7 @@ namespace DD4hep { /// Constructor to be used when creating a new object. Data are taken from the input handle CartesianGridXY() : GridXY("cartesian_grid_xy") {} }; - + /** @class GlobalGridXY Segmentations.h DD4hep/lcdd/Segmentations.h * * @author M.Frank @@ -240,8 +240,8 @@ namespace DD4hep { /// Constructor to be used when creating a new object. Data are taken from the input handle GlobalGridXY() : GridXY("global_grid_xy") {} }; - - + + } /* End namespace Geometry */ } /* End namespace DD4hep */ #endif /* DD4HEP_GEOMETRY_SEGMENTATIONS_H */ diff --git a/DDCore/include/ROOT/LinkDef.h b/DDCore/include/ROOT/LinkDef.h index c592ed6223b0cc83c180c54ef619d255f4569931..50301fde445b62f5cfdd59897cb62aca86498de4 100644 --- a/DDCore/include/ROOT/LinkDef.h +++ b/DDCore/include/ROOT/LinkDef.h @@ -35,6 +35,12 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::Alignment; #pragma link C++ class DD4hep::Geometry::Conditions; #pragma link C++ class DD4hep::Geometry::ProjectiveCylinder; +#pragma link C++ class DD4hep::Geometry::NonProjectiveCylinder; +#pragma link C++ class DD4hep::Geometry::CartesianGridXY; +#pragma link C++ class DD4hep::Geometry::GridXYZ; +#pragma link C++ class DD4hep::Geometry::GlobalGridXY; +#pragma link C++ class DD4hep::Geometry::GridXY; +#pragma link C++ class DD4hep::Geometry::ProjectiveZPlane; #pragma link C++ class DD4hep::Geometry::IDDescriptor; #pragma link C++ namespace DD4hep::Geometry; #pragma link C++ function DD4hep::Geometry::_toDictionary(const std::string&, const std::string&); diff --git a/DDCore/python/lcdd.py b/DDCore/python/lcdd.py index f398cc870ad9601f0867eaeb917f55f627d81531..ace78459ad7adfe85ea610dbda565b0ac880fece 100644 --- a/DDCore/python/lcdd.py +++ b/DDCore/python/lcdd.py @@ -21,7 +21,12 @@ Position = DD4hep.Geometry.Position Rotation = DD4hep.Geometry.Rotation Handle = DD4hep.Geometry.Handle Readout = DD4hep.Geometry.Readout +GridXYZ = DD4hep.Geometry.GridXYZ +GlobalGridXY = DD4hep.Geometry.GlobalGridXY +CartesianGridXY = DD4hep.Geometry.CartesianGridXY ProjectiveCylinder = DD4hep.Geometry.ProjectiveCylinder +NonProjectiveCylinder = DD4hep.Geometry.NonProjectiveCylinder +ProjectiveZPlane = DD4hep.Geometry.ProjectiveZPlane IDDescriptor = DD4hep.Geometry.IDDescriptor _toDictionary = DD4hep.Geometry._toDictionary @@ -330,9 +335,41 @@ def process_readout(lcdd, elem): lcdd.addReadout(readout) #---Segmentations-------------------------------------------------------------------- +def create_GridXYZ(lcdd, elem) : + obj = GridXYZ() + if 'gridSizeX' in elem.keys() : obj.setGridSizeX(elem.getF('gridSizeX')) + if 'gridSizeY' in elem.keys() : obj.setGridSizeY(elem.getF('gridSizeY')) + if 'gridSizeZ' in elem.keys() : obj.setGridSizeZ(elem.getF('gridSizeZ')) + return obj + +def create_GlobalGridXY(lcdd, elem) : + obj = GlobalGridXY() + if 'gridSizeX' in elem.keys() : obj.setGridSizeX(elem.getF('gridSizeX')) + if 'gridSizeY' in elem.keys() : obj.setGridSizeY(elem.getF('gridSizeY')) + return obj + +def create_CartesianGridXY(lcdd, elem) : + obj = CartesianGridXY() + if 'gridSizeX' in elem.keys() : obj.setGridSizeX(elem.getF('gridSizeX')) + if 'gridSizeY' in elem.keys() : obj.setGridSizeY(elem.getF('gridSizeY')) + return obj + def create_ProjectiveCylinder(lcdd, elem) : obj = ProjectiveCylinder() - obj.setPhiBins(elem.getI('phiBins')) - obj.setThetaBins(elem.getI('thetaBins')) + if 'phiBins' in elem.keys() : obj.setPhiBins(elem.getI('phiBins')) + if 'thetaBins' in elem.keys() : obj.setThetaBins(elem.getI('thetaBins')) return obj +def create_NonProjectiveCylinder(lcdd, elem) : + obj = NonProjectiveCylinder() + if 'gridSizePhi' in elem.keys() : obj.setThetaBinSize(elem.getF('gridSizePhi')) + if 'gridSizeZ' in elem.keys() : obj.setPhiBinSize(elem.getI('gridSizeZ')) + return obj + +def create_ProjectiveZPlane(lcdd, elem) : + obj = ProjectiveZPlaner() + if 'phiBins' in elem.keys() : obj.setPhiBins(elem.getI('phiBins')) + if 'thetaBins' in elem.keys() : obj.setThetaBins(elem.getI('thetaBins')) + return obj + + diff --git a/DDExamples/ILDExDet/compact/ILDExTPC.xml b/DDExamples/ILDExDet/compact/ILDExTPC.xml index 917256c71a9b288859bd10d0796aeb2d4cc74b5c..380038d75e9d1e90f6388e6b6de91dff6852531b 100644 --- a/DDExamples/ILDExDet/compact/ILDExTPC.xml +++ b/DDExamples/ILDExDet/compact/ILDExTPC.xml @@ -85,11 +85,11 @@ <rotation x="0" y="0" z="0"/> <modules name="TPC_Module" vis="TPCModuleVis"> - <row type ="TubeSegment" moduleHeight="210" rowPitch="100" modulePitch="35" pads="PadLayout0" nModules="5" RowID="0"/> - <row type ="TubeSegment" moduleHeight="210" rowPitch="100" modulePitch="35" pads="PadLayout1" nModules="9" RowID="1"/> - <row type ="TubeSegment" moduleHeight="210" rowPitch="100" modulePitch="35" pads="PadLayout2" nModules="13" RowID="2"/> - <row type ="TubeSegment" moduleHeight="210" rowPitch="100" modulePitch="35" pads="PadLayout3" nModules="16" RowID="3"/> - <row type ="TubeSegment" moduleHeight="210" rowPitch="100" modulePitch="35" pads="PadLayout4" nModules="20" RowID="4"/> + <row type ="TubeSegment" moduleHeight="210*mm" rowPitch="100*mm" modulePitch="35*mm" pads="PadLayout0" nModules="5" RowID="0"/> + <row type ="TubeSegment" moduleHeight="210*mm" rowPitch="100*mm" modulePitch="35*mm" pads="PadLayout1" nModules="9" RowID="1"/> + <row type ="TubeSegment" moduleHeight="210*mm" rowPitch="100*mm" modulePitch="35*mm" pads="PadLayout2" nModules="13" RowID="2"/> + <row type ="TubeSegment" moduleHeight="210*mm" rowPitch="100*mm" modulePitch="35*mm" pads="PadLayout3" nModules="16" RowID="3"/> + <row type ="TubeSegment" moduleHeight="210*mm" rowPitch="100*mm" modulePitch="35*mm" pads="PadLayout4" nModules="20" RowID="4"/> </modules> </detector> diff --git a/DDExamples/ILDExDet/drivers/TPCPrototype.py b/DDExamples/ILDExDet/drivers/TPCPrototype.py new file mode 100644 index 0000000000000000000000000000000000000000..43b1e6e6eab4cc54fabf48ef58c1d14000b9c4f8 --- /dev/null +++ b/DDExamples/ILDExDet/drivers/TPCPrototype.py @@ -0,0 +1,76 @@ +from ROOT import DD4hep + +#------------------------------------------------------------------------------------- +def detector_TPCPrototype(lcdd, det): + tube = det.find('tubs') + material = det.find('material') + tpc = DetElement(det.name, det.type, det.id, DD4hep.TPCData()) + tpcdata = tpc._data(); + + tpc_tube = Tube(tube.rmin, tube.rmax, tube.zhalf) + tpc_vol = Volume(det.name+'_envelope', tpc_tube, lcdd.material(material.name)) + + for px in det.findall('detector'): + px_tube = px.find('tubs') + px_pos = px.find('position') + px_rot = px.find('rotation') + px_mat = px.find('material') + part_det = DetElement(px.name, px.type, px.id) + part_tube = Tube(px_tube.rmin, px_tube.rmax, px_tube.zhalf) + part_mat = lcdd.material(px_mat.name) + part_vol = Volume(px.name, part_tube, part_mat) + #part_vol.setSensitiveDetector(sens) + part_vol.setVisAttributes(lcdd.visAttributes(px.vis)) + if px.id == 2 : tpcdata.innerWall = part_det + elif px.id == 3 : tpcdata.outerWall = part_det + elif px.id == 4 : tpcdata.gasVolume = part_det + elif px.id == 5 : tpcdata.cathode = part_det + #---Endplate------------------------------------- + if px.id == 0 : + tpcdata.endplate = part_det + mdcount = 0 + for modules in px.findall('modules'): + + for row in modules.findall('row') : + nmodules = row.getI('nModules') + rowID = row.getI('RowID') + pitch = row.getF('modulePitch') + width = row.getF('moduleWidth') + height = row.getF('moduleHeight') + zhalf=px_tube.zhalf + mr_name = modules.name + '_Row%d' % rowID + mr_vol = Volume(mr_name, Box(width/2,height/2,zhalf), part_mat) + mr_mat = lcdd.material(px_mat.name) + xml_pads = lcdd.readout(row.get('pads')) + + for md in range(nmodules): + m_name = modules.name + '_Row%d_M%d' % (rowID,md) + module = DetElement(part_det, m_name, mdcount) + mdcount += 1 + posx = row.getF('modulePosX') + md*(width/2+pitch) + posy = row.getF('modulePosY') + m_phv = part_vol.placeVolume(mr_vol, Position(posx,posy,0), Rotation(0,0,0)) + m_phv.addPhysVolID('module',md) + module.setPlacement(m_phv) + module.setReadout(xml_pads) + #-->module.addExtension<PadLayout>(new FixedPadAngleDiskLayout(module)) + + part_phv = tpc_vol.placeVolume(part_vol, getPosition(px_pos), getRotation(px_rot)) + part_phv.addPhysVolID(px.name, px.id) + part_det.setPlacement(part_phv) + tpc.add(part_det) + #--- now reflect it + if px.getB('reflect'): + r_pos = Position(px_pos.x, px_pos.y, -px_pos.z) + r_rot = Rotation(pi, 0, pi) + part_phv2 = tpc_vol.placeVolume(part_vol, r_pos, r_rot) + part_phv2.addPhysVolID(px.name+"_negativ",px.id+1); + rdet = part_det.clone(px.name+"_negativ",px.id+1) + rdet.setPlacement(part_phv2) + tpcdata. endplate2 = rdet + tpc.add(rdet) + + tpc_vol.setVisAttributes(lcdd.visAttributes(det.vis)) + phv = lcdd.worldVolume().placeVolume(tpc_vol) + tpc.setPlacement(phv) + return tpc