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..5f54fd98f --- /dev/null +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/MuonTaggerPhiTheta.xml @@ -0,0 +1,66 @@ + + + + + + Simple muon tagger with phi-theta segmentation - barrel and endcaps + + + + + + + + + + + + + + + + system:4,subsystem:1,layer:5,theta:10,phi:10 + + + + system:4,subsystem:1,layer:5,theta:10,phi:10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 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 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..cef5f5a54 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,22 @@ 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); + + // 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); + 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..54ef2a071 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,22 @@ 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); + + // 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); + 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..521db6cb3 --- /dev/null +++ b/detector/other/SimpleCylinder_geo_o1_v02.cpp @@ -0,0 +1,173 @@ +#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; + + // get detector name, ID and dimensions from compact file + std::string name = x_det.nameStr(); + int detID = x_det.id(); + xml_comp_t cylinderDim(x_det.child(_U(dimensions))); + + // create the mother Detector element to be returned at the end + dd4hep::DetElement detMaster(name, detID); + + // 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()); + + // define the volume (shape + material) of the detector + 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()); + } + detMaster.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + + // create caloData object and fill rmin, rmax info + auto caloData = new dd4hep::rec::LayeredCalorimeterData; + 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(); + bool isEndcap = (zmin*zmax > 0.); + + if (isEndcap) + { + // 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); + + // link each pv with its corresponding det element + endcapPos.setPlacement( endcapPos_pv ); + endcapNeg.setPlacement( endcapNeg_pv ); + + // set the layer ID of each endcap to 0 + endcapPos_pv.addPhysVolID("layer", 0); + endcapNeg_pv.addPhysVolID("layer", 0); + + // 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; + + 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 + { + // 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); + + // 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; + + 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 + detMaster.addExtension(caloData); + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(x_det, detMaster); + + return detMaster; +} +} +DECLARE_DETELEMENT(SimpleCylinder_o1_v02, det::createSimpleCylinder) + diff --git a/detector/other/SimpleCylinder_geo_o1_v03.cpp b/detector/other/SimpleCylinder_geo_o1_v03.cpp new file mode 100644 index 000000000..f61f4dd7e --- /dev/null +++ b/detector/other/SimpleCylinder_geo_o1_v03.cpp @@ -0,0 +1,309 @@ +#include "DD4hep/DetFactoryHelper.h" +#include +#include "XML/Utilities.h" +#include "DDRec/MaterialManager.h" +#include "DDRec/Vector3D.h" +using dd4hep::_toString; + +#define endmsg std::endl +#define lLog std::cout +namespace MSG { +const std::string ERROR = "createSimpleCylinder ERROR "; +const std::string DEBUG = "createSimpleCylinder DEBUG "; +const std::string INFO = "createSimpleCylinder INFO "; +} + +namespace det { +/** + Simple cylinder using Tube to be used to define cylinder composed of 1 single material + Based on SimpleCylinder_geo_o1_v02.cpp, but with 2 layers (todo: read N layers from xml) + @author G. Marchiori +**/ +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(); + int detID = x_det.id(); + xml_comp_t cylinderDim(x_det.child(_U(dimensions))); + + // retrieve layer information + dd4hep::xml::DetElement layers = x_det.child(_Unicode(layers)); + int nLayers = 0; + std::vector layerDepth; + double layersTotalDepth = 0; + for (dd4hep::xml::Collection_t layer_coll(layers, _Unicode(layer)); layer_coll; ++layer_coll) { + dd4hep::xml::Component layer = layer_coll; + nLayers += layer.repeat(); + for (int iLay = 0; iLay < layer.repeat(); iLay++) { + layerDepth.push_back(layer.thickness()); + } + layersTotalDepth += layer.repeat() * layer.thickness(); + } + lLog << MSG::DEBUG << "Number of layers: " << nLayers << endmsg; + lLog << MSG::DEBUG << "Total thickness from sum of layers in xml description (cm): " << layersTotalDepth/dd4hep::cm << endmsg; + lLog << MSG::INFO << "Ignoring layer thickness from xml description, assuming all layers have same thickness" << endmsg; + + // create the mother Detector element to be returned at the end + dd4hep::DetElement detMaster(name, detID); + + // get the world volume, where the detector will be placed + dd4hep::Volume experimentalHall = lcdd.pickMotherVolume(detMaster); + + // create caloData object and fill rmin, rmax info + auto caloData = new dd4hep::rec::LayeredCalorimeterData; + caloData->extent[0] = cylinderDim.rmin(); + caloData->extent[1] = cylinderDim.rmax(); + + dd4hep::rec::MaterialManager matMgr(experimentalHall); + double zoff = cylinderDim.z_offset(); + double zmin = zoff - cylinderDim.dz(); + double zmax = zoff + cylinderDim.dz(); + bool isEndcap = (zmin*zmax > 0.); + + if (isEndcap) + { + // top volume of endcaps is an assembly + dd4hep::Assembly endcapAssembly("Endcaps_assembly"); + + // top volume element (do I need this?) + // dd4hep::DetElement endcapElement(detMaster); + + // loop over the endcaps + for (int iEndcap = 0; iEndcap<2; iEndcap++) { + // create DetElement for endcap, as daughter of detMaster + dd4hep::DetElement endcap(detMaster); + + // define the tranform for positioning the endcap + double zoffset = iEndcap == 1 ? zoff : -zoff; + int rot = iEndcap == 1 ? 0 : 180; + dd4hep::Transform3D endcap_position(dd4hep::RotationZ( rot*dd4hep::deg), dd4hep::Translation3D(0, 0, zoffset)); + + // define the geometrical shape of the endcap + dd4hep::Tube cylinder( + cylinderDim.rmin(), cylinderDim.rmax(),cylinderDim.dz(), cylinderDim.phi0(), cylinderDim.deltaphi()); + + // define the volume (shape + material) of the detector envelope + dd4hep::Volume cylinderVol( + // x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material(cylinderDim.materialStr())); + x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material("Air")); + + detMaster.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + + // place the endcap + auto endcap_pv = endcapAssembly.placeVolume( cylinderVol, endcap_position ); + + // mark each placed volume (pv) with the proper phys vol ID + endcap_pv.addPhysVolID("subsystem", iEndcap); + + // link each pv with its corresponding det element + endcap.setPlacement( endcap_pv ); + + // segment the endcap into layers + double dzLayer = cylinderDim.dz()*2.0/nLayers; + lLog << MSG::DEBUG << "dZ of each layer : " << dzLayer << endmsg; + for (int iLayer=0; iLayerextent[2] = zmin; + caloData->extent[3] = zmax; + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::EndcapLayout; + + dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; + double dzLayer = cylinderDim.dz()*2.0/nLayers; + auto mat = lcdd.material(cylinderDim.materialStr()); + for (int idxLayer = 0; idxLayer < nLayers; ++idxLayer) { + double zIn = zmin + idxLayer*dzLayer; + // double zOut = zIn + dzLayer; + + caloLayer.distance = zIn; // distance from origin to innermost face of layer + caloLayer.sensitive_thickness = dzLayer; // thickness of the sensitive element + // caloLayer.absorberThickness = 0.0; // thickness of absorber part of layer. consider using inner/outer_nRadiationLenghts and inner/outer_nInteractionLengths + + caloLayer.inner_thickness = dzLayer/2.0; // distance between center of sensitive element and innermost face or layer + caloLayer.inner_nRadiationLengths = caloLayer.inner_thickness / mat.radLength(); // absorber material in front of sensitive element in layer + caloLayer.inner_nInteractionLengths = caloLayer.inner_thickness / mat.intLength(); // absorber material in front of sensitive element in layer + caloLayer.outer_thickness = dzLayer/2.0; // distance between center of sensitive element and outermost face or layer + caloLayer.outer_nRadiationLengths = caloLayer.outer_thickness / mat.radLength(); // absorber material behind sensitive element in layer + caloLayer.outer_nInteractionLengths = caloLayer.outer_thickness / mat.intLength(); // absorber material behind sensitive element in layer + + 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); + } + /* + 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; + */ + } + else + { + // top volume of barrel is an assembly + dd4hep::Assembly barrelAssembly("Barrel_assembly"); + + // top volume element + dd4hep::DetElement barrelElement(detMaster); + + // define the geometrical shape of the barrel + dd4hep::Tube cylinder( + cylinderDim.rmin(), cylinderDim.rmax(),cylinderDim.dz(), cylinderDim.phi0(), cylinderDim.deltaphi()); + + // define the volume (shape + material) of the detector envelope + dd4hep::Volume cylinderVol( + // x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material(cylinderDim.materialStr())); + x_det.nameStr() + "_SimpleCylinder", cylinder, lcdd.material("Air")); + + detMaster.setVisAttributes(lcdd, x_det.visStr(), cylinderVol); + + // place the barrel + auto barrel_pv = barrelAssembly.placeVolume( cylinderVol ); + + // mark each placed volume (pv) with the proper phys vol ID + barrel_pv.addPhysVolID("subsystem", 0); + + // link each pv with its corresponding det element + barrelElement.setPlacement( barrel_pv ); + + // create the layers + double drLayer = (cylinderDim.rmax() - cylinderDim.rmin())/nLayers; + double rIn = cylinderDim.rmin(); + for (int iLayer=0; iLayerextent[2] = 0; + caloData->extent[3] = cylinderDim.dz(); + caloData->layoutType = dd4hep::rec::LayeredCalorimeterData::BarrelLayout; + + auto mat = lcdd.material(cylinderDim.materialStr()); + dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; + for (int idxLayer = 0; idxLayer < nLayers; ++idxLayer) { + rIn = cylinderDim.rmin() + idxLayer*drLayer; + // double rOut = rIn + drLayer; + + caloLayer.distance = rIn; // distance from origin to innermost face of layer + caloLayer.sensitive_thickness = drLayer; // thickness of the sensitive element + // caloLayer.absorberThickness = 0.0; // thickness of absorber part of layer. consider using inner/outer_nRadiationLenghts and inner/outer_nInteractionLengths + + caloLayer.inner_thickness = drLayer/2.0; // distance between center of sensitive element and innermost face or layer + caloLayer.inner_nRadiationLengths = caloLayer.inner_thickness / mat.radLength(); // absorber material in front of sensitive element in layer + caloLayer.inner_nInteractionLengths = caloLayer.inner_thickness / mat.intLength(); // absorber material in front of sensitive element in layer + caloLayer.outer_thickness = drLayer/2.0; // distance between center of sensitive element and outermost face or layer + caloLayer.outer_nRadiationLengths = caloLayer.outer_thickness / mat.radLength(); // absorber material behind sensitive element in layer + caloLayer.outer_nInteractionLengths = caloLayer.outer_thickness / mat.intLength(); // absorber material behind sensitive element in layer + + 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 calo data to the detector + detMaster.addExtension(caloData); + + // Set type flags + dd4hep::xml::setDetectorTypeFlag(x_det, detMaster); + + return detMaster; +} +} +DECLARE_DETELEMENT(SimpleCylinder_o1_v03, det::createSimpleCylinder) + 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);