From 9259e7c3638fd626cec47066d9868f33b296fe14 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Wed, 15 Jan 2025 01:46:57 +0100 Subject: [PATCH 1/9] add detector type, calodata, muon tagger with phi-theta segmentation and simple cylinder geometry with both endcaps in same volume --- .../compact/ALLEGRO_o1_v04/ALLEGRO_o1_v04.xml | 2 +- .../ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml | 50 ++++++ ...leLiquid_InclinedTrapezoids_o1_v03_geo.cpp | 9 +- ...leLiquid_InclinedTrapezoids_o1_v04_geo.cpp | 45 ++++-- .../ECalEndcap_Turbine_o1_v01_geo.cpp | 12 ++ .../ECalEndcap_Turbine_o1_v02_geo.cpp | 12 ++ .../HCalThreePartsEndcap_o1_v02_geo.cpp | 13 +- .../calorimeter/HCalTileBarrel_o1_v02_geo.cpp | 58 +++++-- detector/other/SimpleCylinder_geo_o1_v02.cpp | 144 ++++++++++++++++++ 9 files changed, 313 insertions(+), 32 deletions(-) create mode 100644 FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml create mode 100644 detector/other/SimpleCylinder_geo_o1_v02.cpp diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/ALLEGRO_o1_v04.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/ALLEGRO_o1_v04.xml index 4acb0d6f3..2d30835c1 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/ALLEGRO_o1_v04.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/ALLEGRO_o1_v04.xml @@ -48,7 +48,7 @@ - + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml new file mode 100644 index 000000000..9e16d1a64 --- /dev/null +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml @@ -0,0 +1,50 @@ + + + + + + Simple muon tagger with phi-theta segmentation - barrel and endcaps + + + + + + + + + + + system:4,subsystem:1,layer:5,theta:10,phi:10 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v03_geo.cpp b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v03_geo.cpp index 33a8380f1..daa8f50b0 100644 --- a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v03_geo.cpp +++ b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v03_geo.cpp @@ -683,14 +683,15 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, envelopePhysVol.addPhysVolID("system", xmlDetElem.id()); caloDetElem.setPlacement(envelopePhysVol); - // Create caloData object + // Create caloData object for the reconstruction auto caloData = new dd4hep::rec::LayeredCalorimeterData; caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::BarrelLayout; caloDetElem.addExtension(caloData); - + // Extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm + // (for barrel detectors zmin is 0) caloData->extent[0] = Rmin; - caloData->extent[1] = Rmax; // or r_max ? - caloData->extent[2] = 0.; // NN: for barrel detectors this is 0 + caloData->extent[1] = Rmax; + caloData->extent[2] = 0.; caloData->extent[3] = caloDim.dz(); diff --git a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v04_geo.cpp b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v04_geo.cpp index 61e58fd5e..e03ffc0a9 100644 --- a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v04_geo.cpp +++ b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v04_geo.cpp @@ -753,21 +753,36 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, envelopePhysVol.addPhysVolID("system", xmlDetElem.id()); caloDetElem.setPlacement(envelopePhysVol); - // Create caloData object + // Create caloData object for the reconstruction auto caloData = new dd4hep::rec::LayeredCalorimeterData; caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::BarrelLayout; caloDetElem.addExtension(caloData); + dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); + + // Fill caloData information + // Extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm + // (for barrel detectors zmin is 0) caloData->extent[0] = Rmin; - caloData->extent[1] = Rmax; // or r_max ? - caloData->extent[2] = 0.; // NN: for barrel detectors this is 0 + caloData->extent[1] = Rmax; + caloData->extent[2] = 0.; caloData->extent[3] = caloDim.dz(); - // Set type flags - dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); + // Information about each layer + // double distance : distance from Origin (or the z-axis) to the inner-most face of the layer + // double phi0 : phi0 of layer: potential rotation around normal to absorber plane, e.g. if layers are 'staggered' in phi in fwd. calos + // double absorberThickness : thickness of the absorber part of the layer. Consider using inner/outer_nRadiationLengths and inner/outer_nInteractionLengths + // double inner_nRadiationLengths : Absorber material in front of sensitive element in the layer, units of radiation lengths + // double inner_nInteractionLengths : Absorber material in front of sensitive element in the layer, units of radiation lengths + // double outer_nRadiationLengths : Absorber material in behind of sensitive element in the layer, units of radiation lengths + // double outer_nInteractionLengths : Absorber material in behind of sensitive element in the layer, units of radiation lengths + // double inner_thickness : Distance between the innermost face of the layer (closest to IP) and the center of the sensitive element + // double outer_thickness : Distance between the center of the sensitive element and the outermost face of the layer + // double sensitive_thickness : Thickness of the sensitive element (e.g. scintillator) + // double cellSize0 : cell size along the first axis where first is either along the beam (BarrelLayout) or up (EndcapLayout) or the direction closest to that + // double cellSize1 : second cell size, perpendicular to the first direction cellSize0 and the depth of the layers dd4hep::rec::MaterialManager matMgr(envelopeVol); dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; - double rad_first = Rmin; double rad_last = 0; double scale_fact = dR / (-Rmin * cos(angle) + sqrt(pow(Rmax, 2) - pow(Rmin * sin(angle), 2))); @@ -786,19 +801,19 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, auto mat = matMgr.createAveragedMaterial(materials); // creating average of all the material between two points to calculate X0 and lambda of averaged material const double nRadiationLengths = mat.radiationLength(); const double nInteractionLengths = mat.interactionLength(); - const double difference_bet_r1r2 = (ivr1 - ivr2).r(); - const double value_of_x0 = layerHeight[il] / nRadiationLengths; - const double value_of_lambda = layerHeight[il] / nInteractionLengths; + const double difference_bet_r1r2 = (ivr1 - ivr2).r(); // should be identical to layerHeight[il] * scale_fact + const double value_of_x0 = layerHeight[il] / nRadiationLengths; // GM : shouldn't this be multiplied by scale_fact? + const double value_of_lambda = layerHeight[il] / nInteractionLengths; // GM : shouldn't this be multiplied by scale_fact? std::string str1("LAr"); for (size_t imat = 0; imat < materials.size(); imat++) { std::string str2(materials.at(imat).first.name()); if (str1.compare(str2) == 0){ - thickness_sen += materials.at(imat).second; + thickness_sen += materials.at(imat).second; } else { - absorberThickness += materials.at(imat).second; + absorberThickness += materials.at(imat).second; } } rad_first = rad_last; @@ -807,7 +822,9 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, std::cout << "The radiation length is " << value_of_x0 << " and the interaction length is " << value_of_lambda << std::endl; caloLayer.distance = rad_first; + caloLayer.absorberThickness = absorberThickness; caloLayer.sensitive_thickness = thickness_sen; + caloLayer.inner_nRadiationLengths = value_of_x0 / 2.0; caloLayer.inner_nInteractionLengths = value_of_lambda / 2.0; caloLayer.inner_thickness = difference_bet_r1r2 / 2.0; @@ -816,9 +833,9 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, caloLayer.outer_nInteractionLengths = value_of_lambda / 2.0; caloLayer.outer_thickness = difference_bet_r1r2 / 2; - caloLayer.absorberThickness = absorberThickness; - caloLayer.cellSize0 = 20 * dd4hep::mm; - caloLayer.cellSize1 = 20 * dd4hep::mm; + // GM: rather retrieve cellDimensions vector from segmentation class + caloLayer.cellSize0 = 20 * dd4hep::mm; // GM: rather put delta_eta here and use pandora::POINTING cell type (should actually modify pandora to accept theta grid) + caloLayer.cellSize1 = 20 * dd4hep::mm; // GM: rather delta_phi here + pandora::POINTING cell type caloData->layers.push_back(caloLayer); } diff --git a/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp index 4a4c43822..4c9803603 100644 --- a/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp +++ b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp @@ -1,6 +1,8 @@ #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/Printout.h" #include "TMatrixT.h" +#include "XML/Utilities.h" +#include // todo: remove gaudi logging and properly capture output #define endmsg std::endl @@ -659,6 +661,16 @@ createECalEndcapTurbine(dd4hep::Detector& aLcdd, dd4hep::xml::Handle_t aXmlEleme dd4hep::PlacedVolume envelopePhysVol = motherVol.placeVolume(endcapsAssembly); caloDetElem.setPlacement(envelopePhysVol); envelopePhysVol.addPhysVolID("system", idDet); + + // Create dummy caloData object for PandoraPFA + // FIXME: fill calo and layer data information + auto caloData = new dd4hep::rec::LayeredCalorimeterData; + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; + caloDetElem.addExtension(caloData); + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); + return caloDetElem; } } // namespace det diff --git a/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp b/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp index a8fcafdc5..5d59562dd 100644 --- a/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp +++ b/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp @@ -1,6 +1,8 @@ #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/Printout.h" #include "TMatrixT.h" +#include "XML/Utilities.h" +#include // todo: remove gaudi logging and properly capture output #define endmsg std::endl @@ -663,6 +665,16 @@ namespace det { dd4hep::PlacedVolume envelopePhysVol = motherVol.placeVolume(endcapsAssembly); caloDetElem.setPlacement(envelopePhysVol); envelopePhysVol.addPhysVolID("system", idDet); + + // Create dummy caloData object for PandoraPFA + // FIXME: fill calo and layer data information + auto caloData = new dd4hep::rec::LayeredCalorimeterData; + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; + caloDetElem.addExtension(caloData); + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); + return caloDetElem; } } diff --git a/detector/calorimeter/HCalThreePartsEndcap_o1_v02_geo.cpp b/detector/calorimeter/HCalThreePartsEndcap_o1_v02_geo.cpp index 30235a955..8d86c5d1f 100644 --- a/detector/calorimeter/HCalThreePartsEndcap_o1_v02_geo.cpp +++ b/detector/calorimeter/HCalThreePartsEndcap_o1_v02_geo.cpp @@ -2,6 +2,7 @@ #include "DD4hep/DetFactoryHelper.h" #include #include "DD4hep/Printout.h" +#include "XML/Utilities.h" using dd4hep::Volume; using dd4hep::DetElement; @@ -451,10 +452,10 @@ static dd4hep::Ref_t createHCalEC(dd4hep::Detector& lcdd, xml_h xmlElement, dd4h caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; caloDetElem.addExtension(caloData); - caloData->extent[0] = sensitiveBarrel3Rmin; - caloData->extent[1] = sensitiveBarrel3Rmin + moduleDepth3; // - caloData->extent[2] = 0.; // NN: for barrel detectors this is 0 - caloData->extent[3] = dzDetector1 + dzDetector2 + dzDetector3; + caloData->extent[0] = sensitiveBarrel3Rmin; // innerRCoordinate + caloData->extent[1] = sensitiveBarrel3Rmin + moduleDepth3; // outerRCoordinate + caloData->extent[2] = extBarrelOffset1 - dzDetector1; // innerZCoordinate (start of the first part of the Endcap) + caloData->extent[3] = extBarrelOffset3 + dzDetector3; // outerZCoordinate (end of the third part of the Endcap) dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; @@ -489,6 +490,10 @@ static dd4hep::Ref_t createHCalEC(dd4hep::Detector& lcdd, xml_h xmlElement, dd4h caloData->layers.push_back(caloLayer); } + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(xmlDet, caloDetElem); + return caloDetElem; } }// namespace det diff --git a/detector/calorimeter/HCalTileBarrel_o1_v02_geo.cpp b/detector/calorimeter/HCalTileBarrel_o1_v02_geo.cpp index aaf6c9c4d..797270933 100644 --- a/detector/calorimeter/HCalTileBarrel_o1_v02_geo.cpp +++ b/detector/calorimeter/HCalTileBarrel_o1_v02_geo.cpp @@ -2,6 +2,9 @@ #include "DD4hep/DetFactoryHelper.h" #include #include "DD4hep/Printout.h" +#include "XML/Utilities.h" +#include "DDRec/MaterialManager.h" +#include "DDRec/Vector3D.h" using dd4hep::Volume; using dd4hep::DetElement; @@ -238,22 +241,59 @@ static dd4hep::Ref_t createHCal(dd4hep::Detector& lcdd, xml_det_t xmlDet, dd4hep caloData->extent[2] = 0.; // NN: for barrel detectors this is 0 caloData->extent[3] = dzDetector; + dd4hep::rec::MaterialManager matMgr(envelopeVolume); dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; for (unsigned int idxLayer = 0; idxLayer < layerDepths.size(); ++idxLayer) { - const double difference_bet_r1r2 = layerDepths.at(idxLayer); - - caloLayer.distance = layerInnerRadii.at(idxLayer); // radius of the current layer - caloLayer.sensitive_thickness = difference_bet_r1r2; // radial dimension of the current layer - caloLayer.inner_thickness = difference_bet_r1r2 / 2.0; - caloLayer.outer_thickness = difference_bet_r1r2 / 2.0; - - caloData->layers.push_back(caloLayer); + const double difference_bet_r1r2 = layerDepths.at(idxLayer); + double thickness_sen = 0.; + double absorberThickness = 0.; + + // AD: average material radiation length in a given layer depends on the polar angle... not sure how it is used by Pandora... lets calculate it at the angle of 60 degrees... + const double angle = 60.*M_PI/180.; + dd4hep::rec::Vector3D ivr1 = dd4hep::rec::Vector3D(0., layerInnerRadii.at(idxLayer), 0); // defining starting vector points of the given layer + dd4hep::rec::Vector3D ivr2 = dd4hep::rec::Vector3D(0., layerInnerRadii.at(idxLayer) + layerDepths.at(idxLayer), layerDepths.at(idxLayer)*cos(angle)/sin(angle)); // defining end vector points of the given layer + + const dd4hep::rec::MaterialVec &materials = matMgr.materialsBetween(ivr1, ivr2); // calling material manager to get material info between two points + auto mat = matMgr.createAveragedMaterial(materials); // creating average of all the material between two points to calculate X0 and lambda of averaged material + const double nRadiationLengths = layerDepths.at(idxLayer) / mat.radiationLength(); + const double nInteractionLengths = layerDepths.at(idxLayer) / mat.interactionLength(); + + std::string str1("Polystyrene"); // sensitive material + for (size_t imat = 0; imat < materials.size(); imat++) { + std::string str2(materials.at(imat).first.name()); + if (str1.compare(str2) == 0){ + thickness_sen += materials.at(imat).second; + } + else if(str2!="Air") { + absorberThickness += materials.at(imat).second; + } + } + std::cout << "The sensitive thickness is " << thickness_sen << std::endl; + std::cout << "The absorber thickness is " << absorberThickness << std::endl; + std::cout << "The number of radiation length is " << nRadiationLengths << " and the number of interaction length is " << nInteractionLengths << std::endl; + + caloLayer.distance = layerInnerRadii.at(idxLayer); // radius of the current layer + caloLayer.sensitive_thickness = difference_bet_r1r2; // radial dimension of the current layer + //caloLayer.sensitive_thickness = thickness_sen; + caloLayer.absorberThickness = absorberThickness; + + caloLayer.inner_thickness = difference_bet_r1r2 / 2.0; + caloLayer.inner_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.inner_nInteractionLengths = nInteractionLengths / 2.0; + caloLayer.outer_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.outer_nInteractionLengths = nInteractionLengths / 2.0; + caloLayer.outer_thickness = difference_bet_r1r2 / 2; + + caloLayer.cellSize0 = 20 * dd4hep::mm; // should be updated from DDGeometryCreatorALLEGRO + caloLayer.cellSize1 = 20 * dd4hep::mm; // should be updated from DDGeometryCreatorALLEGRO + caloData->layers.push_back(caloLayer); } + // Set type flags + dd4hep::xml::setDetectorTypeFlag(xmlDet, caloDetElem); return caloDetElem; - } } // namespace hcal diff --git a/detector/other/SimpleCylinder_geo_o1_v02.cpp b/detector/other/SimpleCylinder_geo_o1_v02.cpp new file mode 100644 index 000000000..38c138442 --- /dev/null +++ b/detector/other/SimpleCylinder_geo_o1_v02.cpp @@ -0,0 +1,144 @@ +#include "DD4hep/DetFactoryHelper.h" +#include +#include "XML/Utilities.h" +#include "DDRec/MaterialManager.h" +#include "DDRec/Vector3D.h" + + +namespace det { +/** + Simple cylinder using Tube to be used to define cylinder composed of 1 single material + Based on SimpleCylinder_geo_o1_v01.cpp prepared by Clement Helsens + When used for an endcap detector, create both endcap physical volumes and places them + in a single detector + @author A. Durglishvili + @author G. Marchiori +**/ +static dd4hep::Ref_t +createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector sensDet) { + xml_det_t x_det = e; + std::string name = x_det.nameStr(); + dd4hep::DetElement cylinderDet(name, x_det.id()); + + dd4hep::Volume experimentalHall = lcdd.pickMotherVolume(cylinderDet); + + xml_comp_t cylinderDim(x_det.child(_U(dimensions))); + + dd4hep::Tube cylinder( + cylinderDim.rmin(), cylinderDim.rmax(), cylinderDim.dz(), cylinderDim.phi0(), cylinderDim.deltaphi()); + + dd4hep::Volume cylinderVol( + x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material(cylinderDim.materialStr())); + + if (x_det.isSensitive()) { + dd4hep::xml::Dimension sdType(x_det.child(_U(sensitive))); + cylinderVol.setSensitiveDetector(sensDet); + sensDet.setType(sdType.typeStr()); + } + + // Create caloData object + auto caloData = new dd4hep::rec::LayeredCalorimeterData; + dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; + dd4hep::rec::MaterialManager matMgr(experimentalHall); + + caloData->extent[0] = cylinderDim.rmin(); + caloData->extent[1] = cylinderDim.rmax(); + + double zoff = cylinderDim.z_offset(); + double zmin = zoff - cylinderDim.dz(); + double zmax = zoff + cylinderDim.dz(); + bool isEndcap = (zmin*zmax > 0.); + + if (isEndcap) + { + dd4hep::PlacedVolume cylinderPhys1; // negative endcap + dd4hep::PlacedVolume cylinderPhys2; // positive endcap + dd4hep::Position trans1(0., 0., -zoff); + dd4hep::Position trans2(0., 0., zoff); + cylinderPhys1 = experimentalHall.placeVolume(cylinderVol, dd4hep::Transform3D(dd4hep::RotationZ(0.), trans1)); + cylinderPhys2 = experimentalHall.placeVolume(cylinderVol, dd4hep::Transform3D(dd4hep::RotationZ(0.), trans2)); + + cylinderPhys1.addPhysVolID("system", x_det.id()); + cylinderPhys1.addPhysVolID("subsystem", 0); // negative endcap + cylinderPhys1.addPhysVolID("layer", 0); + + cylinderPhys2.addPhysVolID("system", x_det.id()); + cylinderPhys1.addPhysVolID("subsystem", 1); // positive endcap + cylinderPhys2.addPhysVolID("layer", 0); + + cylinderDet.setPlacement(cylinderPhys1); + cylinderDet.setPlacement(cylinderPhys2); + cylinderDet.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + + caloData->extent[2] = zmin; + caloData->extent[3] = zmax; + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; + + dd4hep::rec::Vector3D ivr1 = dd4hep::rec::Vector3D(0., 0., zmin); // defining starting vector points + dd4hep::rec::Vector3D ivr2 = dd4hep::rec::Vector3D(0., 0., zmax); // defining end vector + + const dd4hep::rec::MaterialVec &materials = matMgr.materialsBetween(ivr1, ivr2); // calling material manager to get material info between two points + auto mat = matMgr.createAveragedMaterial(materials); // creating average of all the material between two points to calculate X0 and lambda of averaged material + const double nRadiationLengths = cylinderDim.dz()*2. / mat.radiationLength(); + const double nInteractionLengths = cylinderDim.dz()*2. / mat.interactionLength(); + + caloLayer.distance = zmin; + caloLayer.sensitive_thickness = cylinderDim.dz()*2.; + caloLayer.inner_thickness = cylinderDim.dz(); + caloLayer.outer_thickness = cylinderDim.dz(); + + caloLayer.inner_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.inner_nInteractionLengths = nInteractionLengths / 2.0; + caloLayer.outer_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.outer_nInteractionLengths = nInteractionLengths / 2.0; + } + else + { + dd4hep::PlacedVolume cylinderPhys; + cylinderPhys = experimentalHall.placeVolume(cylinderVol); + + cylinderPhys.addPhysVolID("system", x_det.id()); + cylinderPhys.addPhysVolID("layer", 0); + cylinderDet.setPlacement(cylinderPhys); + cylinderDet.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + + caloData->extent[2] = 0; + caloData->extent[3] = cylinderDim.dz(); + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::BarrelLayout; + + dd4hep::rec::Vector3D ivr1 = dd4hep::rec::Vector3D(0., cylinderDim.rmin(), 0.); // defining starting vector points + dd4hep::rec::Vector3D ivr2 = dd4hep::rec::Vector3D(0., cylinderDim.rmax(), 0.); // defining end vector + + const dd4hep::rec::MaterialVec &materials = matMgr.materialsBetween(ivr1, ivr2); // calling material manager to get material info between two points + auto mat = matMgr.createAveragedMaterial(materials); // creating average of all the material between two points to calculate X0 and lambda of averaged material + const double nRadiationLengths = (cylinderDim.rmax() - cylinderDim.rmin()) / mat.radiationLength(); + const double nInteractionLengths = (cylinderDim.rmax() - cylinderDim.rmin()) / mat.interactionLength(); + + caloLayer.distance = cylinderDim.rmin(); + caloLayer.sensitive_thickness = (cylinderDim.rmax() - cylinderDim.rmin()); + caloLayer.inner_thickness = (cylinderDim.rmax() - cylinderDim.rmin()) / 2.0; + caloLayer.outer_thickness = (cylinderDim.rmax() - cylinderDim.rmin()) / 2.0; + + caloLayer.inner_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.inner_nInteractionLengths = nInteractionLengths / 2.0; + caloLayer.outer_nRadiationLengths = nRadiationLengths / 2.0; + caloLayer.outer_nInteractionLengths = nInteractionLengths / 2.0; + } + + caloLayer.cellSize0 = 20 * dd4hep::mm; // FIXME! AD: should be corrected from DDGeometryCreatorALLEGRO. GM: get it from segmentation class + caloLayer.cellSize1 = 20 * dd4hep::mm; // FIXME! AD: should be corrected from DDGeometryCreatorALLEGRO. GM: get it from segmentation class + + // attach the layer to the caloData + caloData->layers.push_back(caloLayer); + + // attach the layer to the cylinderDet + cylinderDet.addExtension(caloData); + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(x_det, cylinderDet); + + return cylinderDet; +} +} +DECLARE_DETELEMENT(SimpleCylinder_o1_v02, det::createSimpleCylinder) + From a9c89b89878d7f1fc9cfa9855e8c2f441c750679 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Wed, 15 Jan 2025 23:20:31 +0100 Subject: [PATCH 2/9] move to phi-theta grid for muon tagger and use volume compatible with pandora --- .../compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml | 2 +- .../ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml index 0d478c06e..aa821a3ad 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml @@ -48,7 +48,7 @@ - + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml new file mode 100644 index 000000000..9e16d1a64 --- /dev/null +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml @@ -0,0 +1,50 @@ + + + + + + Simple muon tagger with phi-theta segmentation - barrel and endcaps + + + + + + + + + + + system:4,subsystem:1,layer:5,theta:10,phi:10 + + + + + + + + + + + + + + + + + + + + + + + + From 7a4153d9852ea08e4c101a7c5fb26963f846a090 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Mon, 20 Jan 2025 22:51:09 +0100 Subject: [PATCH 3/9] add extent info to ecal endcap turbine class --- detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp | 6 ++++++ detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp index 4c9803603..cef5f5a54 100644 --- a/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp +++ b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp @@ -668,6 +668,12 @@ createECalEndcapTurbine(dd4hep::Detector& aLcdd, dd4hep::xml::Handle_t aXmlEleme caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; caloDetElem.addExtension(caloData); + // save extent information + caloData->extent[0] = dim.rmin1(); + caloData->extent[1] = dim.rmax1(); + caloData->extent[2] = dim.z_offset()-dim.dz()/2.; + caloData->extent[3] = dim.z_offset()+dim.dz()/2.; + // Set type flags dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); diff --git a/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp b/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp index 5d59562dd..54ef2a071 100644 --- a/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp +++ b/detector/calorimeter/ECalEndcap_Turbine_o1_v02_geo.cpp @@ -672,6 +672,12 @@ namespace det { caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; caloDetElem.addExtension(caloData); + // save extent information + caloData->extent[0] = dim.rmin1(); + caloData->extent[1] = dim.rmax1(); + caloData->extent[2] = dim.z_offset()-dim.dz()/2.; + caloData->extent[3] = dim.z_offset()+dim.dz()/2.; + // Set type flags dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); From 60a2e95c3901a82565af4b795fd3adffb304e7a3 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Thu, 23 Jan 2025 14:10:10 +0100 Subject: [PATCH 4/9] fix typo --- detector/other/SimpleCylinder_geo_o1_v02.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detector/other/SimpleCylinder_geo_o1_v02.cpp b/detector/other/SimpleCylinder_geo_o1_v02.cpp index 38c138442..7bb189ca0 100644 --- a/detector/other/SimpleCylinder_geo_o1_v02.cpp +++ b/detector/other/SimpleCylinder_geo_o1_v02.cpp @@ -63,7 +63,7 @@ createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector cylinderPhys1.addPhysVolID("layer", 0); cylinderPhys2.addPhysVolID("system", x_det.id()); - cylinderPhys1.addPhysVolID("subsystem", 1); // positive endcap + cylinderPhys2.addPhysVolID("subsystem", 1); // positive endcap cylinderPhys2.addPhysVolID("layer", 0); cylinderDet.setPlacement(cylinderPhys1); From f7294b12d8ea5eca8b6a472a5455266bc66870e2 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Mon, 27 Jan 2025 13:37:58 +0100 Subject: [PATCH 5/9] fix bug with endcap building --- detector/other/SimpleCylinder_geo_o1_v02.cpp | 99 +++++++++++++------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/detector/other/SimpleCylinder_geo_o1_v02.cpp b/detector/other/SimpleCylinder_geo_o1_v02.cpp index 7bb189ca0..521db6cb3 100644 --- a/detector/other/SimpleCylinder_geo_o1_v02.cpp +++ b/detector/other/SimpleCylinder_geo_o1_v02.cpp @@ -17,33 +17,39 @@ namespace det { static dd4hep::Ref_t createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector sensDet) { xml_det_t x_det = e; + + // get detector name, ID and dimensions from compact file std::string name = x_det.nameStr(); - dd4hep::DetElement cylinderDet(name, x_det.id()); + int detID = x_det.id(); + xml_comp_t cylinderDim(x_det.child(_U(dimensions))); - dd4hep::Volume experimentalHall = lcdd.pickMotherVolume(cylinderDet); + // create the mother Detector element to be returned at the end + dd4hep::DetElement detMaster(name, detID); - xml_comp_t cylinderDim(x_det.child(_U(dimensions))); + // get the world volume, where the detector will be placed + dd4hep::Volume experimentalHall = lcdd.pickMotherVolume(detMaster); + // define the geometrical shape of the detector (barrel or each endcap) dd4hep::Tube cylinder( - cylinderDim.rmin(), cylinderDim.rmax(), cylinderDim.dz(), cylinderDim.phi0(), cylinderDim.deltaphi()); + cylinderDim.rmin(), cylinderDim.rmax(),cylinderDim.dz(), cylinderDim.phi0(), cylinderDim.deltaphi()); + // define the volume (shape + material) of the detector dd4hep::Volume cylinderVol( - x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material(cylinderDim.materialStr())); - + x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material(cylinderDim.materialStr())); if (x_det.isSensitive()) { dd4hep::xml::Dimension sdType(x_det.child(_U(sensitive))); cylinderVol.setSensitiveDetector(sensDet); sensDet.setType(sdType.typeStr()); } + detMaster.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); - // Create caloData object + // create caloData object and fill rmin, rmax info auto caloData = new dd4hep::rec::LayeredCalorimeterData; - dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; - dd4hep::rec::MaterialManager matMgr(experimentalHall); - caloData->extent[0] = cylinderDim.rmin(); caloData->extent[1] = cylinderDim.rmax(); - + + dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; + dd4hep::rec::MaterialManager matMgr(experimentalHall); double zoff = cylinderDim.z_offset(); double zmin = zoff - cylinderDim.dz(); double zmax = zoff + cylinderDim.dz(); @@ -51,25 +57,43 @@ createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector if (isEndcap) { - dd4hep::PlacedVolume cylinderPhys1; // negative endcap - dd4hep::PlacedVolume cylinderPhys2; // positive endcap - dd4hep::Position trans1(0., 0., -zoff); - dd4hep::Position trans2(0., 0., zoff); - cylinderPhys1 = experimentalHall.placeVolume(cylinderVol, dd4hep::Transform3D(dd4hep::RotationZ(0.), trans1)); - cylinderPhys2 = experimentalHall.placeVolume(cylinderVol, dd4hep::Transform3D(dd4hep::RotationZ(0.), trans2)); + // create DetElements for each endcap, as daughters of detMaster + dd4hep::DetElement endcapPos(detMaster); + dd4hep::DetElement endcapNeg(detMaster); + + // define the tranforms for positioning the two endcaps + dd4hep::Transform3D endcapPos_position(dd4hep::RotationZ( 000*dd4hep::deg), dd4hep::Translation3D(0, 0, zoff)); + dd4hep::Transform3D endcapNeg_position(dd4hep::RotationZ( 180*dd4hep::deg), dd4hep::Translation3D(0, 0, -zoff)); + + // top volume of endcaps is an assembly + dd4hep::Assembly endcapAssembly("Endcaps_assembly"); + + // place the endcap on the right and left + auto endcapPos_pv = endcapAssembly.placeVolume( cylinderVol, endcapPos_position ); + auto endcapNeg_pv = endcapAssembly.placeVolume( cylinderVol, endcapNeg_position ); + + // mark each placed volume (pv) with the proper phys vol ID + endcapPos_pv.addPhysVolID("subsystem", 1); + endcapNeg_pv.addPhysVolID("subsystem", 0); - cylinderPhys1.addPhysVolID("system", x_det.id()); - cylinderPhys1.addPhysVolID("subsystem", 0); // negative endcap - cylinderPhys1.addPhysVolID("layer", 0); + // link each pv with its corresponding det element + endcapPos.setPlacement( endcapPos_pv ); + endcapNeg.setPlacement( endcapNeg_pv ); - cylinderPhys2.addPhysVolID("system", x_det.id()); - cylinderPhys2.addPhysVolID("subsystem", 1); // positive endcap - cylinderPhys2.addPhysVolID("layer", 0); + // set the layer ID of each endcap to 0 + endcapPos_pv.addPhysVolID("layer", 0); + endcapNeg_pv.addPhysVolID("layer", 0); - cylinderDet.setPlacement(cylinderPhys1); - cylinderDet.setPlacement(cylinderPhys2); - cylinderDet.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + // place the assembly volume in the world + auto endcapAssembly_pv = experimentalHall.placeVolume(endcapAssembly); + // assign the system ID to the assembly volume + endcapAssembly_pv.addPhysVolID("system", detID); + + // link volume with top DetElement to be returned + detMaster.setPlacement(endcapAssembly_pv); + + // fill the caloData info caloData->extent[2] = zmin; caloData->extent[3] = zmax; caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; @@ -94,14 +118,19 @@ createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector } else { - dd4hep::PlacedVolume cylinderPhys; - cylinderPhys = experimentalHall.placeVolume(cylinderVol); + // place the volume in the world + auto barrel_pv = experimentalHall.placeVolume(cylinderVol); + + // assign the system ID to the volume + barrel_pv.addPhysVolID("system", x_det.id()); + + // Set layer ID to 0 + barrel_pv.addPhysVolID("layer", 0); - cylinderPhys.addPhysVolID("system", x_det.id()); - cylinderPhys.addPhysVolID("layer", 0); - cylinderDet.setPlacement(cylinderPhys); - cylinderDet.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + // link volume with top DetElement to be returned + detMaster.setPlacement(barrel_pv); + // Fill caloData object caloData->extent[2] = 0; caloData->extent[3] = cylinderDim.dz(); caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::BarrelLayout; @@ -132,12 +161,12 @@ createSimpleCylinder(dd4hep::Detector& lcdd, xml_h e, dd4hep::SensitiveDetector caloData->layers.push_back(caloLayer); // attach the layer to the cylinderDet - cylinderDet.addExtension(caloData); + detMaster.addExtension(caloData); // Set type flags - dd4hep::xml::setDetectorTypeFlag(x_det, cylinderDet); + dd4hep::xml::setDetectorTypeFlag(x_det, detMaster); - return cylinderDet; + return detMaster; } } DECLARE_DETELEMENT(SimpleCylinder_o1_v02, det::createSimpleCylinder) From 922e4ce71c9ee51979fbf69476b30d35d20a2f80 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Mon, 27 Jan 2025 17:48:12 +0100 Subject: [PATCH 6/9] introduce separate readouts for muon barrel and endcap --- .../compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml index 9e16d1a64..7b4b0713b 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml @@ -19,7 +19,11 @@ - + + + system:4,subsystem:1,layer:5,theta:10,phi:10 + + system:4,subsystem:1,layer:5,theta:10,phi:10 @@ -27,7 +31,7 @@ - + @@ -36,7 +40,7 @@ dz="MuonTagger_half_length" z_offset = "0" material="Polystyrene" phi0="0" deltaphi="360*deg" vis="muon_vis"/> - + From e8b4d82862e7b8081f873b0c667364140776a3c0 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Mon, 27 Jan 2025 17:48:33 +0100 Subject: [PATCH 7/9] remove commented code --- detectorSegmentations/src/FCCSWGridPhiTheta_k4geo.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/detectorSegmentations/src/FCCSWGridPhiTheta_k4geo.cpp b/detectorSegmentations/src/FCCSWGridPhiTheta_k4geo.cpp index e4f709d59..30c6b131a 100644 --- a/detectorSegmentations/src/FCCSWGridPhiTheta_k4geo.cpp +++ b/detectorSegmentations/src/FCCSWGridPhiTheta_k4geo.cpp @@ -42,12 +42,6 @@ CellID FCCSWGridPhiTheta_k4geo::cellID(const Vector3D& /* localPosition */, cons return cID; } -/// determine the azimuthal angle phi based on the current cell ID -//double FCCSWGridPhiTheta_k4geo::phi() const { -// CellID phiValue = (*_decoder)[m_phiID].value(); -// return binToPosition(phiValue, 2. * M_PI / (double)m_phiBins, m_offsetPhi); -//} - /// determine the azimuthal angle phi based on the cell ID double FCCSWGridPhiTheta_k4geo::phi(const CellID& cID) const { CellID phiValue = _decoder->get(cID, m_phiID); From 1cef8c7ea3312263402d71436d63e6e90370502e Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Mon, 27 Jan 2025 18:45:09 +0100 Subject: [PATCH 8/9] fix xml --- FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml index 7b4b0713b..8a7d359e0 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml @@ -30,7 +30,7 @@ - + @@ -40,6 +40,7 @@ dz="MuonTagger_half_length" z_offset = "0" material="Polystyrene" phi0="0" deltaphi="360*deg" vis="muon_vis"/> + From a8b9b0944a54b95afde42fa7e96e5b603853bdff Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori Date: Tue, 28 Jan 2025 16:22:14 +0100 Subject: [PATCH 9/9] use same muon detector for ALLEGRO v03 and v04 --- .../ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml | 51 +------------------ 1 file changed, 1 insertion(+), 50 deletions(-) mode change 100644 => 120000 FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml deleted file mode 100644 index 9e16d1a64..000000000 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - Simple muon tagger with phi-theta segmentation - barrel and endcaps - - - - - - - - - - - system:4,subsystem:1,layer:5,theta:10,phi:10 - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml new file mode 120000 index 000000000..71ab67eb7 --- /dev/null +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v04/MuonTaggerPhiTheta.xml @@ -0,0 +1 @@ +../ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml \ No newline at end of file