diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt index 4d4bbb85c2ec04fc52271cf583c25c5b8a44994e..c12345980bc7f150cf4d385a79a2b0db929e3c49 100644 --- a/DDCore/CMakeLists.txt +++ b/DDCore/CMakeLists.txt @@ -12,7 +12,7 @@ if(DD4HEP_USE_PYROOT) file(GLOB headers include/DD4hep/*.h) list(REMOVE_ITEM headers ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/DetFactoryHelper.h ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/Factories.h) - ROOT_GENERATE_DICTIONARY( G__DD4hep ${headers} LINKDEF include/ROOT/LinkDef.h) + root_generate_dictionary( G__DD4hep ${headers} LINKDEF include/ROOT/LinkDef.h) list(APPEND sources G__DD4hep.cxx) add_definitions(-DDD4HEP_USE_PYROOT) set(libraries ${libraries} PyROOT) diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 54881cb1adc70c8c43d81b68326a4ff0dc8fee6e..321c4b74b8b6e077b3bc39a1f085370f336ca705 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -237,6 +237,10 @@ namespace DD4hep { /// Default constructor template<typename Q> DetElement(Q* data, const std::string& name, const std::string& type) : Ref_t(data) { this->assign(data, name, type); } + + template<typename Q> DetElement(const std::string& name, const std::string& type, int id, const Q&) + { assign(new Value<TNamed,Q>(),name,type); + _data().id = id; } /// Templated constructor for handle conversions template<typename Q> DetElement(const Handle<Q>& e) : Ref_t(e) {} diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 0793aa320b163be5fe31407c4da68c8c7f658185..a73b1fc746349a7e8aef928b2f85199c00469a7e 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -185,13 +185,12 @@ namespace DD4hep { static LCDD& getInstance(void); }; - /* * The following are convenience implementations to access constants by type. * I do not think this violates the interface approach, but it is so much * more intuitiv to say constant<int>(name) than constantAsInt(name). */ - +#ifndef __CINT__ /// Typed access to constants: short values template <> inline short LCDD::constant<short>(const std::string& name) const { return (short)constantAsLong(name); } @@ -227,7 +226,7 @@ namespace DD4hep { /// Typed access to constants: string values template <> inline std::string LCDD::constant<std::string>(const std::string& name) const { return constantAsString(name); } - +#endif } /* End namespace Geometry */ } /* End namespace DD4hep */ #endif /* DD4HEP_LCDD_LCDD_H */ diff --git a/DDCore/include/ROOT/LinkDef.h b/DDCore/include/ROOT/LinkDef.h index acf47cb145259002a15f78e3f287282a3c554df2..c592ed6223b0cc83c180c54ef619d255f4569931 100644 --- a/DDCore/include/ROOT/LinkDef.h +++ b/DDCore/include/ROOT/LinkDef.h @@ -23,6 +23,7 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::Limit; #pragma link C++ class DD4hep::Geometry::AlignmentEntry; #pragma link C++ class DD4hep::Geometry::DetElement; +#pragma link C++ class DD4hep::Geometry::DetElement::Object; #pragma link C++ class DD4hep::Geometry::Box; #pragma link C++ class DD4hep::Geometry::Tube; #pragma link C++ class DD4hep::Geometry::Trapezoid; @@ -30,6 +31,11 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::PlacedVolume; #pragma link C++ class DD4hep::Geometry::Position; #pragma link C++ class DD4hep::Geometry::Rotation; +#pragma link C++ class DD4hep::Geometry::Readout; +#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::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 9d9e379f4e33998048612222fc66395b7f1a2130..f398cc870ad9601f0867eaeb917f55f627d81531 100644 --- a/DDCore/python/lcdd.py +++ b/DDCore/python/lcdd.py @@ -20,6 +20,10 @@ PlacedVolume = DD4hep.Geometry.PlacedVolume Position = DD4hep.Geometry.Position Rotation = DD4hep.Geometry.Rotation Handle = DD4hep.Geometry.Handle +Readout = DD4hep.Geometry.Readout +ProjectiveCylinder = DD4hep.Geometry.ProjectiveCylinder +IDDescriptor = DD4hep.Geometry.IDDescriptor + _toDictionary = DD4hep.Geometry._toDictionary import xml.etree.ElementTree as xml @@ -115,17 +119,27 @@ def process_xmlfile(lcdd, file): file = file.replace('file:','') root = xml.parse(file).getroot() last_xmlfile, current_xmlfile = current_xmlfile, file - for e in root : - if e.tag == 'detectors' : - lcdd.init() # call init before processing 'detectors' (need world volume) - procs = globals().get('process_%s'% e.tag, None) - if not procs : - procs = drivers.get('process_%s'% e.tag, None) - if procs : - apply(procs,(lcdd, e)) - else : print 'XML tag %s not processed!!! No function found.' % e.tag + tags = ('includes', 'define', 'materials', 'properties', 'limits', 'display', + 'readouts', 'detectors', 'alignments', 'fields', 'sensitive_detectors') + if root.tag in tags : + process_tag(lcdd, root) + else : + for tag in tags: + for e in root.findall(tag): + process_tag(lcdd, e) current_xmlfile = last_xmlfile +def process_tag(lcdd, elem): + if elem.tag == 'detectors' : + lcdd.init() # call init before processing 'detectors' (need world volume) + procs = globals().get('process_%s'% elem.tag, None) + if not procs : + procs = drivers.get('process_%s'% elem.tag, None) + if procs : + apply(procs,(lcdd, elem)) + else : print 'XML tag %s not processed!!! No function found.' % elem.tag + + #-------------------------------------------------------------------------------- def fromXML(xmlfile): print 'Converting Compact file: ', xmlfile @@ -289,5 +303,36 @@ def process_alignment(lcdd, elem): alignment.align(pos,rot) return alignment +#----------------------------------------------------------------------------------- +def process_readouts(lcdd, elem): + for a in elem.findall('readout'): + process_readout(lcdd, a) +#----------------------------------------------------------------------------------- +def process_readout(lcdd, elem): + readout = Readout(elem.name) + seg = elem.find('segmentation') + if seg is not None: + procs = globals().get('create_%s'% seg.get('type'), None) + if not procs : + procs = drivers.get('create_%s'% seg.get('type'), None) + if procs : + segment = apply(procs,(lcdd, seg)) + readout.setSegmentation(segment) + else : + print 'Segmentation type %s not found' % seg.get('type') + id = elem.find('id') + if id is not None: + idSpec = IDDescriptor(id.text) + idSpec.SetName(elem.name) + readout.setIDDescriptor(idSpec) + lcdd.addIDSpecification(idSpec) + lcdd.addReadout(readout) + +#---Segmentations-------------------------------------------------------------------- +def create_ProjectiveCylinder(lcdd, elem) : + obj = ProjectiveCylinder() + obj.setPhiBins(elem.getI('phiBins')) + obj.setThetaBins(elem.getI('thetaBins')) + return obj diff --git a/DDExamples/ILDExDet/drivers/ILDExTPC.py b/DDExamples/ILDExDet/drivers/ILDExTPC.py index c579ecbddd77c839b441bcaa8150c257cd9e6c8f..4f8506999400caf1ff0cde341af22d49d7a4b492 100644 --- a/DDExamples/ILDExDet/drivers/ILDExTPC.py +++ b/DDExamples/ILDExDet/drivers/ILDExTPC.py @@ -4,8 +4,10 @@ from ROOT import DD4hep def detector_ILDExTPC(lcdd, det): tube = det.find('tubs') material = det.find('material') - tpc_de = DD4hep.ILDExTPC(det.name, det.type, det.id) - tpc_tube = Tube(det.name+'_tube', tube.rmin, tube.rmax, tube.zhalf) + 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'): @@ -14,20 +16,59 @@ def detector_ILDExTPC(lcdd, det): px_rot = px.find('rotation') px_mat = px.find('material') part_det = DetElement(px.name, px.type, px.id) - part_tube = Tube(px.name+'_tube',px_tube.rmin, px_tube.rmax, px_tube.zhalf) - part_vol = Volume(px.name, part_tube, lcdd.material(px_mat.name)) + 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)) - part_det.setPlacement(tpc_vol.placeVolume(part_vol, getPosition(px_pos), getRotation(px_rot))) - if px.id == 0 : tpc_de.setInnerWall(part_det) - elif px.id == 1 : tpc_de.setOuterWall(part_det) - elif px.id == 2 : tpc_de.setEndPlate(part_det,1) - elif px.id == 5 : tpc_de.setGasVolume(part_det) - tpc_de.add(part_det) + 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('rowPitch') + rmin = px_tube.rmin + pitch/2 + rowID*row.getF('moduleHeight') + rowID*pitch/2 + rmax = rmin + row.getF('moduleHeight') + DeltaPhi = (2*pi - nmodules*(row.getF('modulePitch')/(rmin+(rmax-rmin)/2)))/nmodules + zhalf=px_tube.zhalf + mr_name = modules.name + '_Row%d' % rowID + mr_vol = Volume(mr_name, Tube(rmin,rmax,zhalf,DeltaPhi), 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 + rotz = md*2*pi/nmodules + row.getF('modulePitch')/(rmin+(rmax-rmin))/2 + m_phv = part_vol.placeVolume(mr_vol, Position(0,0,0), Rotation(0,0,rotz)) + 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)) - lcdd.worldVolume().placeVolume(tpc_vol) - #--additonal TPC data----------------------------- - mod = det.find('module') - tpc_de.setNModules(mod.getI('number')) - tpc_de.setDriftLength(mod.getF('driftlength')) - - return tpc_de + phv = lcdd.worldVolume().placeVolume(tpc_vol) + tpc.setPlacement(phv) + return tpc diff --git a/DDExamples/ILDExDet/include/ROOT/LinkDef.h b/DDExamples/ILDExDet/include/ROOT/LinkDef.h index 65a9a28d88a7df4249e5358fdc41781d8e8540d9..901971d3b14845925b8e37d6969ce1269ab9cebc 100644 --- a/DDExamples/ILDExDet/include/ROOT/LinkDef.h +++ b/DDExamples/ILDExDet/include/ROOT/LinkDef.h @@ -13,7 +13,10 @@ #pragma link off all functions; //---Specific detector---------------------------- -#pragma link C++ class DD4hep::ILDExTPC; +//#pragma link C++ class DD4hep::ILDExTPC; #pragma link C++ class DD4hep::TPCData; +#pragma link C++ class DD4hep::Geometry::Value<TNamed,DD4hep::TPCData>; +#pragma link C++ function DD4hep::Geometry::DetElement::DetElement(const std::string&, const std::string&, int, const DD4hep::TPCData&); + #endif diff --git a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp index 158c03f3bb2d3c887a65e91caf1cd13d68937b93..ce941ba884a9b7c67e583be636d17201482ac09f 100644 --- a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp +++ b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp @@ -23,7 +23,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) xml_comp_t x_tube (x_det.child(_X(tubs))); string name = x_det.nameStr(); Material mat (lcdd.material(x_det.materialStr())); - //if data is needed do this + //if data is needed do this Value<TNamed,TPCData>* tpcData = new Value<TNamed,TPCData>(); DetElement tpc(tpcData, name, x_det.typeStr()); tpcData->id = x_det.id(); @@ -31,7 +31,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) //DetElement tpc (name,x_det.typeStr(),x_det.id()); Tube tpc_tub(x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); Volume tpc_vol(name+"_envelope_volume", tpc_tub, mat); - + for(xml_coll_t c(e,_X(detector)); c; ++c) { xml_comp_t px_det (c); xml_comp_t px_tube (px_det.child(_X(tubs))); @@ -46,61 +46,61 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) Position part_pos(px_pos.x(),px_pos.y(),px_pos.z()); Rotation part_rot(px_rot.x(),px_rot.y(),px_rot.z()); bool reflect = px_det.reflect(); - + part_vol.setSensitiveDetector(sens); part_vol.setVisAttributes(lcdd,px_det.visStr()); //cache the important volumes in TPCData for later use without having to know their name switch(part_det.id()) - { + { case 2: - tpcData->innerWall=part_det; + tpcData->innerWall=part_det; case 3: - tpcData->outerWall=part_det; + tpcData->outerWall=part_det; case 4: - tpcData->gasVolume=part_det; + tpcData->gasVolume=part_det; case 5: - tpcData->cathode=part_det; - } + tpcData->cathode=part_det; + } //Endplate if(part_det.id()== 0){ tpcData->endplate=part_det; //modules int mdcount=0; for(xml_coll_t m(px_det,_X(modules)); m; ++m) { - xml_comp_t modules (m); - string m_name = modules.nameStr(); - for(xml_coll_t r(modules,_X(row)); r; ++r) { - xml_comp_t row(r); - int nmodules = row.nModules(); - int rowID=row.RowID(); - //shape of module - double pitch=row.rowPitch(); - double rmin=px_tube.rmin()+pitch/2+rowID*row.moduleHeight()+rowID*pitch/2; - double rmax=rmin+row.moduleHeight(); - double DeltaPhi=(2*M_PI-nmodules*(row.modulePitch()/(rmin+(rmax-rmin)/2)))/nmodules; - double zhalf=px_tube.zhalf(); - string mr_nam=m_name+_toString(rowID,"_Row%d"); - Volume mr_vol(mr_nam,Tube(rmin,rmax,zhalf,DeltaPhi),part_mat); - Material mr_mat(lcdd.material(px_mat.nameStr())); - Readout xml_pads(lcdd.readout(row.padType())); - - //placing modules - for(int md=0;md<nmodules;md++){ - string m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d"); - - DetElement module(part_det,m_nam,mdcount); - mdcount++; - double rotz=md*2*M_PI/nmodules+row.modulePitch()/(rmin+(rmax-rmin))/2; - PlacedVolume m_phv = part_vol.placeVolume(mr_vol,Position(0,0,0),Rotation(0,0,rotz)); - m_phv.addPhysVolID("module",md); - module.setPlacement(m_phv); - - module.setReadout(xml_pads); - // Readout and placement must be present before adding extension, - // since they are aquired internally for optimisation reasons. (MF) - module.addExtension<PadLayout>(new FixedPadAngleDiskLayout(module)); - }//modules - }//rows + xml_comp_t modules (m); + string m_name = modules.nameStr(); + for(xml_coll_t r(modules,_X(row)); r; ++r) { + xml_comp_t row(r); + int nmodules = row.nModules(); + int rowID=row.RowID(); + //shape of module + double pitch=row.rowPitch(); + double rmin=px_tube.rmin()+pitch/2+rowID*row.moduleHeight()+rowID*pitch/2; + double rmax=rmin+row.moduleHeight(); + double DeltaPhi=(2*M_PI-nmodules*(row.modulePitch()/(rmin+(rmax-rmin)/2)))/nmodules; + double zhalf=px_tube.zhalf(); + string mr_nam=m_name+_toString(rowID,"_Row%d"); + Volume mr_vol(mr_nam,Tube(rmin,rmax,zhalf,DeltaPhi),part_mat); + Material mr_mat(lcdd.material(px_mat.nameStr())); + Readout xml_pads(lcdd.readout(row.padType())); + + //placing modules + for(int md=0;md<nmodules;md++){ + string m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d"); + + DetElement module(part_det,m_nam,mdcount); + mdcount++; + double rotz=md*2*M_PI/nmodules+row.modulePitch()/(rmin+(rmax-rmin))/2; + PlacedVolume m_phv = part_vol.placeVolume(mr_vol,Position(0,0,0),Rotation(0,0,rotz)); + m_phv.addPhysVolID("module",md); + module.setPlacement(m_phv); + + module.setReadout(xml_pads); + // Readout and placement must be present before adding extension, + // since they are aquired internally for optimisation reasons. (MF) + module.addExtension<PadLayout>(new FixedPadAngleDiskLayout(module)); + }//modules + }//rows }//module groups }//endplate @@ -118,7 +118,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) part_phv2.addPhysVolID(part_nam+"_negativ",px_det.id()+1); // needs a copy function for DetElement // DetElement rdet(lcdd,part_nam+"_negativ",px_det.typeStr(),px_det.id()+1); - DetElement rdet = part_det.clone(part_nam+"_negativ",px_det.id()+1); + DetElement rdet = part_det.clone(part_nam+"_negativ",px_det.id()+1); rdet.setPlacement(part_phv2); tpcData->endplate2=rdet; tpc.add(rdet); diff --git a/DDExamples/ILDExDet/src/compact/TPCPrototype_geo.cpp b/DDExamples/ILDExDet/src/compact/TPCPrototype_geo.cpp index 4ee5d5d875c716fb51fe3785e093225dce3b0123..25700f71b1d342339bcac006bb3eab575953f1e5 100644 --- a/DDExamples/ILDExDet/src/compact/TPCPrototype_geo.cpp +++ b/DDExamples/ILDExDet/src/compact/TPCPrototype_geo.cpp @@ -23,7 +23,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) xml_comp_t x_tube (x_det.child(_X(tubs))); string name = x_det.nameStr(); Material mat (lcdd.material(x_det.materialStr())); - //if data is needed do this + //if data is needed do this Value<TNamed,TPCData>* tpcData = new Value<TNamed,TPCData>(); DetElement tpc(tpcData, name, x_det.typeStr()); tpcData->id = x_det.id(); @@ -31,7 +31,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) // DetElement tpc (name,x_det.typeStr(),x_det.id()); Tube tpc_tub(x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); Volume tpc_vol(name+"_envelope_volume", tpc_tub, mat); - + for(xml_coll_t c(e,_X(detector)); c; ++c) { xml_comp_t px_det (c); xml_comp_t px_tube (px_det.child(_X(tubs))); @@ -46,58 +46,58 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) Position part_pos(px_pos.x(),px_pos.y(),px_pos.z()); Rotation part_rot(px_rot.x(),px_rot.y(),px_rot.z()); bool reflect = px_det.reflect(); - + part_vol.setVisAttributes(lcdd,px_det.visStr()); //cache the important volumes in TPCData for later use without having to know their name switch(part_det.id()) - { + { case 2: - tpcData->innerWall=part_det; + tpcData->innerWall=part_det; case 3: - tpcData->outerWall=part_det; + tpcData->outerWall=part_det; case 4: - tpcData->gasVolume=part_det; + tpcData->gasVolume=part_det; case 5: - tpcData->cathode=part_det; - } - //Endplate + tpcData->cathode=part_det; + } + //Endplate if(part_det.id()== 0){ - tpcData->endplate=part_det; - //modules + tpcData->endplate=part_det; + //modules int mdcount=0; for(xml_coll_t m(px_det,_X(modules)); m; ++m) { - xml_comp_t modules (m); - string m_name = modules.nameStr(); - for(xml_coll_t r(modules,_X(row)); r; ++r) { - xml_comp_t row(r); - int nmodules = row.nModules(); - int rowID=row.RowID(); - //shape of module - double pitch=row.modulePitch(); - double height=row.moduleHeight(); - double width=row.moduleWidth(); - double zhalf=px_tube.zhalf(); - string mr_nam=m_name+_toString(rowID,"_Row%d"); - Volume mr_vol(mr_nam,Box(width/2,height/2,zhalf),part_mat); - Material mr_mat(lcdd.material(px_mat.nameStr())); - Readout xml_pads(lcdd.readout(row.padType())); - - //placing modules - for(int md=0;md<nmodules;md++){ - string m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d"); - DetElement module(part_det,m_nam,mdcount); - mdcount++; - double posx=row.modulePosX()+md*(width/2+pitch); - double posy=row.modulePosY(); - PlacedVolume 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); - // Readout and placement must be present before adding extension, - // since they are aquired internally for optimisation reasons. (MF) - module.addExtension<PadLayout>(new RectangularPadRowLayout(module)); - }//modules - }//rows + xml_comp_t modules (m); + string m_name = modules.nameStr(); + for(xml_coll_t r(modules,_X(row)); r; ++r) { + xml_comp_t row(r); + int nmodules = row.nModules(); + int rowID=row.RowID(); + //shape of module + double pitch=row.modulePitch(); + double height=row.moduleHeight(); + double width=row.moduleWidth(); + double zhalf=px_tube.zhalf(); + string mr_nam=m_name+_toString(rowID,"_Row%d"); + Volume mr_vol(mr_nam,Box(width/2,height/2,zhalf),part_mat); + Material mr_mat(lcdd.material(px_mat.nameStr())); + Readout xml_pads(lcdd.readout(row.padType())); + + //placing modules + for(int md=0;md<nmodules;md++){ + string m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d"); + DetElement module(part_det,m_nam,mdcount); + mdcount++; + double posx=row.modulePosX()+md*(width/2+pitch); + double posy=row.modulePosY(); + PlacedVolume 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); + // Readout and placement must be present before adding extension, + // since they are aquired internally for optimisation reasons. (MF) + module.addExtension<PadLayout>(new RectangularPadRowLayout(module)); + }//modules + }//rows }//module groups }//endplate @@ -115,7 +115,7 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) part_phv2.addPhysVolID(part_nam+"_negativ",px_det.id()+1); // needs a copy function for DetElement // DetElement rdet(lcdd,part_nam+"_negativ",px_det.typeStr(),px_det.id()+1); - DetElement rdet = part_det.clone(part_nam+"_negativ",px_det.id()+1); + DetElement rdet = part_det.clone(part_nam+"_negativ",px_det.id()+1); rdet.setPlacement(part_phv2); tpcData->endplate2=rdet; tpc.add(rdet); diff --git a/DDExamples/ILDExDet/src/VersatileDiskRowLayoutSegXML.cpp b/DDExamples/ILDExDet/src/compact/VersatileDiskRowLayoutSeg_geo.cpp similarity index 100% rename from DDExamples/ILDExDet/src/VersatileDiskRowLayoutSegXML.cpp rename to DDExamples/ILDExDet/src/compact/VersatileDiskRowLayoutSeg_geo.cpp diff --git a/DDG4/CMakeLists.txt b/DDG4/CMakeLists.txt index 3d36251d60845a53ae4a353273d0bb169865969c..fa490ee1cd5ce641e4658dbee837d6fb8efe5766 100644 --- a/DDG4/CMakeLists.txt +++ b/DDG4/CMakeLists.txt @@ -8,7 +8,6 @@ endif() if(DD4HEP_USE_XERCESC) add_definitions(-DDD4HEP_USE_XERCESC) - set(libraries ${libraries} Reflex) endif() #---Includedirs------------------------------------------------------------------- @@ -20,6 +19,9 @@ include_directories(${CMAKE_SOURCE_DIR}/DDCore/include #---Add Library------------------------------------------------------------------- file(GLOB sources src/*.cpp) +if(NOT DD4HEP_USE_XERCESC) + list(REMOVE_ITEM sources ${CMAKE_CURRENT_SOURCE_DIR}/src/Geant4XML.cpp) +endif() add_library(DD4hepG4 SHARED ${sources}) -target_link_libraries(DD4hepG4 DD4hepCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES}) +target_link_libraries(DD4hepG4 DD4hepCore ${ROOT_LIBRARIES} Reflex ${Geant4_LIBRARIES}) #target_link_libraries(DD4hepG4 DD4hepCore ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${Geant4_LIBRARIES}) diff --git a/DDG4/include/DDG4/Geant4SensitiveDetector.h b/DDG4/include/DDG4/Geant4SensitiveDetector.h index 79ad52cc7fb4f2d1f2503ed89c0dbfcbb8dcbbee..aa83c5a92d1d833ea0452a6435b4d522110575fd 100644 --- a/DDG4/include/DDG4/Geant4SensitiveDetector.h +++ b/DDG4/include/DDG4/Geant4SensitiveDetector.h @@ -80,7 +80,7 @@ namespace DD4hep { virtual ~Geant4SensitiveDetector(); /// Standard access to the name - const std::string& name() const { return GetName(); } + std::string name() const { return GetName(); } /// Create single hits collection virtual HitCollection* createCollection(const std::string& coll_name) const; diff --git a/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h b/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h index 3e61e769db50ba088093f82ed24d1ac1c31299ae..7c7d6d61c70118bd13b6bbb102cf15ec30e8acfd 100644 --- a/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h +++ b/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h @@ -52,6 +52,7 @@ template<class SD> G4bool DD4hep::Simulation::Geant4GenericSD<SD>::ProcessHits(G /// Method for generating hit(s) using the information of G4Step object. template<class SD> bool DD4hep::Simulation::Geant4GenericSD<SD>::buildHits(G4Step*,G4TouchableHistory*) { + return true; } diff --git a/DDG4/src/Geant4SensitiveDetector.cpp b/DDG4/src/Geant4SensitiveDetector.cpp index ca296215a9c4082fae0f44cc786bb8dfd0bfda5f..da8e8d773065b8508efe7862d61e9f925b25a563 100644 --- a/DDG4/src/Geant4SensitiveDetector.cpp +++ b/DDG4/src/Geant4SensitiveDetector.cpp @@ -47,6 +47,7 @@ bool Geant4SensitiveDetector::defineCollection(const string& coll_name) { " of type "+string(m_sensitive.type())); } collectionName.insert(coll_name); + return true; } /// Access HitCollection container names diff --git a/ReadMe.txt b/ReadMe.txt index afcf8a13f209aa3860fb51d974bdbb3ebaf3b319..92774d2463c864e7f316a5de24f08d2c1cf8d2b8 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -73,6 +73,13 @@ make -j4 cmake -DDD4HEP_USE_XERCESC=ON -DDD4HEP_USE_PYROOT=OFF -DXERCESC_ROOT_DIR=<xercesc> ../DD4hep + +- Setup the running environment + +. thisdd4hep.sh + or +source thisdd4hep.csh + - Run ILDEx display DDExamples/ILDExDisplay/ILDExDisplay file:../DD4hep/DDExamples/ILDExDet/compact/ILDEx.xml diff --git a/cmake/FindGeant4.cmake b/cmake/FindGeant4.cmake index bb80f5fd526f4a1c35d2a8e24c705c1d644a7b90..9a9ad39f7ea66a7711d58e4c9acea1c8200aaf8b 100644 --- a/cmake/FindGeant4.cmake +++ b/cmake/FindGeant4.cmake @@ -71,7 +71,7 @@ endif() # If we're on UNIX, see if we can find clhep-config and use its --prefix # as an extra hint. # -set(_Geant4_root_hints ${Geant4_ROOT_DIR}) +set(_Geant4_root_hints ${Geant4_ROOT_DIR} ${Geant4_ROOT_DIR}/.. ) #---------------------------------------------------------------------------- # Find the Geant4 headers diff --git a/cmake/FindROOT.cmake b/cmake/FindROOT.cmake index 3c697673b04957a4f576c343803eee722f79016b..17e7ff8d53f9d02814b216bca94130ed74a33c8d 100644 --- a/cmake/FindROOT.cmake +++ b/cmake/FindROOT.cmake @@ -10,11 +10,7 @@ find_program(ROOT_CONFIG_EXECUTABLE root-config PATHS $ENV{ROOTSYS}/bin) -if(NOT ROOT_CONFIG_EXECUTABLE) - set(ROOT_FOUND FALSE) -else() - set(ROOT_FOUND TRUE) - +if(ROOT_CONFIG_EXECUTABLE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix OUTPUT_VARIABLE ROOTSYS @@ -35,29 +31,28 @@ else() OUTPUT_VARIABLE ROOT_LIBRARIES OUTPUT_STRIP_TRAILING_WHITESPACE) - #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lThread -lMinuit -lHtml -lVMC -lEG -lGeom -lTreePlayer -lXMLIO -lProof) - #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lProofPlayer -lMLP -lSpectrum -lEve -lRGL -lGed -lXMLParser -lPhysics) set(ROOT_LIBRARY_DIR ${ROOTSYS}/lib) - #set(ROOT_LIBRARIES -L${ROOT_LIBRARY_DIR} Core Cint) # Make variables changeble to the advanced user mark_as_advanced(ROOT_CONFIG_EXECUTABLE) - if(NOT ROOT_FIND_QUIETLY) - message(STATUS "Found ROOT ${ROOT_VERSION} in ${ROOTSYS}") - endif() endif() +# handle the QUIETLY and REQUIRED arguments and set ROOT_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ROOT DEFAULT_MSG ROOTSYS ROOT_INCLUDE_DIR) +mark_as_advanced(ROOT_FOUND ROOT_INCLUDE_DIR) include(CMakeParseArguments) find_program(ROOTCINT_EXECUTABLE rootcint PATHS $ENV{ROOTSYS}/bin) #---------------------------------------------------------------------------- -# function ROOT_GENERATE_DICTIONARY( dictionary +# function root_generate_dictionary( dictionary # header1 header2 ... # LINKDEF linkdef1 ... # OPTIONS opt1...) -function(ROOT_GENERATE_DICTIONARY dictionary) +function(root_generate_dictionary dictionary) CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS" "" ${ARGN}) #---Get the list of header files------------------------- set(headerfiles)