From f746db9f9df15f2df27a1884504d375c5c3dae92 Mon Sep 17 00:00:00 2001 From: Christian Grefe <Christian.Grefe@cern.ch> Date: Tue, 4 Nov 2014 17:01:00 +0000 Subject: [PATCH] Updated example to show how to use DDRec interface in PolyhedraBarrelCalorimeter2 --- examples/CLICSiD/CMakeLists.txt | 10 +- examples/CLICSiD/CalorimeterReco.cpp | 27 +- .../src/PolyhedraBarrelCalorimeter2_geo.cpp | 317 +++++++++--------- 3 files changed, 175 insertions(+), 179 deletions(-) diff --git a/examples/CLICSiD/CMakeLists.txt b/examples/CLICSiD/CMakeLists.txt index b6ccf8c92..de12fa6ae 100644 --- a/examples/CLICSiD/CMakeLists.txt +++ b/examples/CLICSiD/CMakeLists.txt @@ -31,13 +31,13 @@ ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -find_package( DD4hep ) +find_package( DD4hep ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${DD4hep_ROOT}/cmake ) include( DD4hep ) -find_package( ROOT REQUIRED ) -#find_package( ROOT REQUIRED COMPONENTS Geom Reflex) +#find_package( ROOT REQUIRED ) +find_package( ROOT REQUIRED COMPONENTS Geom Reflex) set( ROOT_COMPONENT_LIBRARIES Geom Reflex) #------------------------------------------------------------- @@ -64,10 +64,10 @@ endif() add_library(${PackageName} SHARED ${sources}) -#add_executable(CalorimeterReco CalorimeterReco.cpp) +add_executable(CalorimeterReco CalorimeterReco.cpp) target_link_libraries(${PackageName} ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES} ) -#target_link_libraries(CalorimeterReco ${PackageName} ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES} ) +target_link_libraries(CalorimeterReco ${PackageName} ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES} ) #---Rootmap generation-------------------------------------------------------------- diff --git a/examples/CLICSiD/CalorimeterReco.cpp b/examples/CLICSiD/CalorimeterReco.cpp index 3cb960543..8fb94093b 100644 --- a/examples/CLICSiD/CalorimeterReco.cpp +++ b/examples/CLICSiD/CalorimeterReco.cpp @@ -6,32 +6,31 @@ */ #include "DD4hep/LCDD.h" -#include "BarrelDetector.h" -#include "PolyhedralBarrelCalorimeter.h" -#include "Calorimeter.h" +#include "DDRec/API/Calorimeter.h" using namespace std; using namespace DD4hep; +using namespace DDRec; using namespace Geometry; void printCalorimeterInformation(const DetElement& det) { std::string delimiter = "-------------------------------------\n"; cout << "Detector name: " << det.name() << ", type: " << det.type() << endl; - PolyhedralCalorimeter calorimeter(det); + Calorimeter calorimeter(det); cout << delimiter << "Layer interface:" << endl; - cout << "\tNumber of layers: " << calorimeter.getNumberOfLayers() << endl; - cout << "\tTotal thickness: " << calorimeter.getTotalThickness() << " cm" << endl; - cout << "\tTotal interaction lengths: " << calorimeter.getTotalInteractionLengths() << " Lambda_int" << endl; - cout << "\tTotal radiation lengths: " << calorimeter.getTotalRadiationLengths() << " X_0" << endl; - for (int layerIndex = 1; layerIndex <= calorimeter.getNumberOfLayers(); layerIndex++) { - cout << "\t\tLayer " << layerIndex << ": d = " << calorimeter.getLayerThickness(layerIndex) - << " cm , Lambda/Lambda_int = " << calorimeter.getInteractionLengths(layerIndex) << ", X/X_0 = " - << calorimeter.getRadiationLengths(layerIndex) << ", Sensors: " - << calorimeter.getNumberOfSensors(layerIndex) << endl; + cout << "\tNumber of layers: " << calorimeter.numberOfLayers() << endl; + cout << "\tTotal thickness: " << calorimeter.totalThickness() << " cm" << endl; + cout << "\tTotal interaction lengths: " << calorimeter.totalInteractionLength() << " Lambda_int" << endl; + cout << "\tTotal radiation lengths: " << calorimeter.totalRadiationLength() << " X_0" << endl; + for (int layerIndex = 1; layerIndex <= calorimeter.numberOfLayers(); layerIndex++) { + cout << "\t\tLayer " << layerIndex << ": d = " << calorimeter.thickness(layerIndex) + << " cm , Lambda/Lambda_int = " << calorimeter.interactionLength(layerIndex) << ", X/X_0 = " + << calorimeter.radiationLength(layerIndex) << ", Sensors: " + << calorimeter.numberOfSensors(layerIndex) << endl; } - cout << delimiter << "Polyhedra interface:" << endl; + cout << delimiter << "Subdetector interface:" << endl; cout << "\tInner radius: " << calorimeter.getRMin() << " cm" << endl; cout << "\tOuter radius: " << calorimeter.getRMax() << " cm" << endl; cout << "\tMinimum z: " << calorimeter.getZMin() << " cm" << endl; diff --git a/examples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp b/examples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp index 91a17ab90..a20463e4a 100644 --- a/examples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp +++ b/examples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp @@ -9,173 +9,170 @@ #include "DD4hep/DetFactoryHelper.h" #include "XML/Layering.h" -#include "LayerStack.h" +#include "DDRec/Extensions/LayeringExtensionImpl.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -static void placeStaves(DetElement& parent, - DetElement& stave, - double rmin, - int numsides, - double total_thickness, - Volume envelopeVolume, - double innerAngle, - Volume sectVolume) -{ - double innerRotation = innerAngle; - double offsetRotation = -innerRotation / 2; - double sectCenterRadius = rmin + total_thickness / 2; - double rotX = M_PI / 2; - double rotY = -offsetRotation; - double posX = -sectCenterRadius * std::sin(rotY); - double posY = sectCenterRadius * std::cos(rotY); - - for (int module = 1; module <= numsides; ++module) { - DetElement det = module>1 ? stave.clone(_toString(module,"stave%d")) : stave; - PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Transform3D(RotationZYX(0,rotY,rotX), - Translation3D(-posX,-posY,0))); - // Not a valid volID: pv.addPhysVolID("stave", 0); - pv.addPhysVolID("module",module); - det.setPlacement(pv); - parent.add(det); - rotY -= innerRotation; - posX = -sectCenterRadius * std::sin(rotY); - posY = sectCenterRadius * std::cos(rotY); - } +static void placeStaves(DetElement& parent, DetElement& stave, double rmin, int numsides, double total_thickness, + Volume envelopeVolume, double innerAngle, Volume sectVolume) { + double innerRotation = innerAngle; + double offsetRotation = -innerRotation / 2; + double sectCenterRadius = rmin + total_thickness / 2; + double rotX = M_PI / 2; + double rotY = -offsetRotation; + double posX = -sectCenterRadius * std::sin(rotY); + double posY = sectCenterRadius * std::cos(rotY); + + for (int module = 1; module <= numsides; ++module) { + DetElement det = module > 1 ? stave.clone(_toString(module, "stave%d")) : stave; + PlacedVolume pv = envelopeVolume.placeVolume(sectVolume, + Transform3D(RotationZYX(0, rotY, rotX), Translation3D(-posX, -posY, 0))); + // Not a valid volID: pv.addPhysVolID("stave", 0); + pv.addPhysVolID("module", module); + det.setPlacement(pv); + parent.add(det); + rotY -= innerRotation; + posX = -sectCenterRadius * std::sin(rotY); + posY = sectCenterRadius * std::cos(rotY); + } } -static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { - xml_det_t x_det = e; - Layering layering(x_det); - xml_comp_t staves = x_det.staves(); - xml_dim_t dim = x_det.dimensions(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - Material air = lcdd.air(); - double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; - double gap = xml_dim_t(x_det).gap(); - int numSides = dim.numsides(); - double detZ = dim.z(); - double rmin = dim.rmin(); - DetElement sdet(det_name,x_det.id()); - DetElement stave("stave1",x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - - for(xml_coll_t c(x_det,_U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - - PolyhedraRegular polyhedra(numSides,rmin,rmin+totalThickness,detZ); - Volume envelopeVol(det_name+"_envelope",polyhedra,air); - - // Add the subdetector envelope to the structure. - double innerAngle = 2*M_PI/numSides; - double halfInnerAngle = innerAngle/2; - double tan_inner = std::tan(halfInnerAngle) * 2; - double innerFaceLen = rmin * tan_inner; - double outerFaceLen = (rmin+totalThickness) * tan_inner; - double staveThickness = totalThickness; - - Trapezoid staveTrdOuter(innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2); - Volume staveOuterVol(det_name+"_stave",staveTrdOuter,air); - - Trapezoid staveTrdInner(innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2); - Volume staveInnerVol(det_name+"_inner",staveTrdInner,air); - - double layerOuterAngle = (M_PI-innerAngle)/2; - double layerInnerAngle = (M_PI/2 - layerOuterAngle); - double layer_pos_z = -(staveThickness / 2); - double layer_dim_x = innerFaceLen/2 - gap * 2; - int layer_num = 1; - - // Set envelope volume attributes. - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - - for(xml_coll_t c(x_det,_U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); // Get number of times to repeat this layer. - const Layer* lay = layering.layer(layer_num-1); // Get the layer from the layering engine. - // Loop over repeats for this layer. - for (int j = 0; j < repeat; j++) { - string layer_name = det_name+_toString(layer_num,"_layer%d"); - double layer_thickness = lay->thickness(); - DetElement layer(stave,_toString(layer_num,"layer%d"),x_det.id()); - - // Layer position in Z within the stave. - layer_pos_z += layer_thickness / 2; - // Layer box & volume - Volume layer_vol(layer_name, Box(layer_dim_x,detZ/2,layer_thickness/2), air); - - // Create the slices (sublayers) within the layer. - double slice_pos_z = -(layer_thickness / 2); - int slice_number = 1; - for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { - xml_comp_t x_slice = k; - string slice_name = layer_name + _toString(slice_number,"_slice%d"); - double slice_thickness = x_slice.thickness(); - Material slice_material = lcdd.material(x_slice.materialStr()); - DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); - - slice_pos_z += slice_thickness / 2; - // Slice volume & box - Volume slice_vol(slice_name,Box(layer_dim_x,detZ/2,slice_thickness/2),slice_material); - - if ( x_slice.isSensitive() ) { - sens.setType("calorimeter"); - slice_vol.setSensitiveDetector(sens); +static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + Layering layering(x_det); + xml_comp_t staves = x_det.staves(); + xml_dim_t dim = x_det.dimensions(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Material air = lcdd.air(); + double totalThickness = layering.totalThickness(); + int totalRepeat = 0; + int totalSlices = 0; + double gap = xml_dim_t(x_det).gap(); + int numSides = dim.numsides(); + double detZ = dim.z(); + double rmin = dim.rmin(); + DetElement sdet(det_name, x_det.id()); + DetElement stave("stave1", x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + + for (xml_coll_t c(x_det, _U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + totalRepeat += repeat; + totalSlices += x_layer.numChildren(_U(slice)); + } + + PolyhedraRegular polyhedra(numSides, rmin, rmin + totalThickness, detZ); + Volume envelopeVol(det_name + "_envelope", polyhedra, air); + + // Add the subdetector envelope to the structure. + double innerAngle = 2 * M_PI / numSides; + double halfInnerAngle = innerAngle / 2; + double tan_inner = std::tan(halfInnerAngle) * 2; + double innerFaceLen = rmin * tan_inner; + double outerFaceLen = (rmin + totalThickness) * tan_inner; + double staveThickness = totalThickness; + + Trapezoid staveTrdOuter(innerFaceLen / 2, outerFaceLen / 2, detZ / 2, detZ / 2, staveThickness / 2); + Volume staveOuterVol(det_name + "_stave", staveTrdOuter, air); + + Trapezoid staveTrdInner(innerFaceLen / 2 - gap, outerFaceLen / 2 - gap, detZ / 2, detZ / 2, staveThickness / 2); + Volume staveInnerVol(det_name + "_inner", staveTrdInner, air); + + double layerOuterAngle = (M_PI - innerAngle) / 2; + double layerInnerAngle = (M_PI / 2 - layerOuterAngle); + double layer_pos_z = -(staveThickness / 2); + double layer_dim_x = innerFaceLen / 2 - gap * 2; + int layer_num = 1; + + DDRec::LayeringExtensionImpl* layeringExtension = new DDRec::LayeringExtensionImpl(); + Position layerNormal(0,0,1); + + // Set envelope volume attributes. + envelopeVol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(), x_det.visStr()); + + for (xml_coll_t c(x_det, _U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); // Get number of times to repeat this layer. + const Layer* lay = layering.layer(layer_num - 1); // Get the layer from the layering engine. + // Loop over repeats for this layer. + for (int j = 0; j < repeat; j++) { + string layer_name = det_name + _toString(layer_num, "_layer%d"); + double layer_thickness = lay->thickness(); + DetElement layer(stave, _toString(layer_num, "layer%d"), x_det.id()); + layeringExtension->setLayer(layer_num, layer, layerNormal); + + // Layer position in Z within the stave. + layer_pos_z += layer_thickness / 2; + // Layer box & volume + Volume layer_vol(layer_name, Box(layer_dim_x, detZ / 2, layer_thickness / 2), air); + + // Create the slices (sublayers) within the layer. + double slice_pos_z = -(layer_thickness / 2); + int slice_number = 1; + for (xml_coll_t k(x_layer, _U(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = layer_name + _toString(slice_number, "_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = lcdd.material(x_slice.materialStr()); + DetElement slice(layer, _toString(slice_number, "slice%d"), x_det.id()); + + slice_pos_z += slice_thickness / 2; + // Slice volume & box + Volume slice_vol(slice_name, Box(layer_dim_x, detZ / 2, slice_thickness / 2), slice_material); + + if (x_slice.isSensitive()) { + sens.setType("calorimeter"); + slice_vol.setSensitiveDetector(sens); + } + // Set region, limitset, and vis. + slice_vol.setAttributes(lcdd, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); + // slice PlacedVolume + PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z)); + slice_phv.addPhysVolID("slice", slice_number); + + slice.setPlacement(slice_phv); + // Increment Z position for next slice. + slice_pos_z += slice_thickness / 2; + // Increment slice number. + ++slice_number; + } + // Set region, limitset, and vis. + layer_vol.setAttributes(lcdd, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); + + // Layer physical volume. + PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol, Position(0, 0, layer_pos_z)); + layer_phv.addPhysVolID("layer", layer_num); + layer.setPlacement(layer_phv); + + // Increment the layer X dimension. + layer_dim_x += layer_thickness * std::tan(layerInnerAngle); // * 2; + // Increment the layer Z position. + layer_pos_z += layer_thickness / 2; + // Increment the layer number. + ++layer_num; + } } - // Set region, limitset, and vis. - slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - // slice PlacedVolume - PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); - slice_phv.addPhysVolID("slice",slice_number); - - slice.setPlacement(slice_phv); - // Increment Z position for next slice. - slice_pos_z += slice_thickness / 2; - // Increment slice number. - ++slice_number; - } - // Set region, limitset, and vis. - layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); - - // Layer physical volume. - PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol,Position(0,0,layer_pos_z)); - layer_phv.addPhysVolID("layer",layer_num); - layer.setPlacement(layer_phv); - - // Increment the layer X dimension. - layer_dim_x += layer_thickness * std::tan(layerInnerAngle);// * 2; - // Increment the layer Z position. - layer_pos_z += layer_thickness / 2; - // Increment the layer number. - ++layer_num; - } - } - - // Add stave inner physical volume to outer stave volume. - staveOuterVol.placeVolume(staveInnerVol); - // Set the vis attributes of the outer stave section. - stave.setVisAttributes(lcdd,staves.visStr(),staveOuterVol); - // Place the staves. - placeStaves(sdet,stave,rmin,numSides,totalThickness,envelopeVol,innerAngle,staveOuterVol); - - double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0; - Transform3D transform(RotationZ(M_PI/numSides),Translation3D(0,0,z_offset)); - PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,transform); - env_phv.addPhysVolID("system", sdet.id()); - env_phv.addPhysVolID("barrel", 0); - sdet.setPlacement(env_phv); - - sdet.addExtension<Geometry::LayerStack>(new Geometry::PolyhedralCalorimeterLayerStack(sdet)); - return sdet; + + // Add stave inner physical volume to outer stave volume. + staveOuterVol.placeVolume(staveInnerVol); + // Set the vis attributes of the outer stave section. + stave.setVisAttributes(lcdd, staves.visStr(), staveOuterVol); + // Place the staves. + placeStaves(sdet, stave, rmin, numSides, totalThickness, envelopeVol, innerAngle, staveOuterVol); + + double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0; + Transform3D transform(RotationZ(M_PI / numSides), Translation3D(0, 0, z_offset)); + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol, transform); + env_phv.addPhysVolID("system", sdet.id()); + env_phv.addPhysVolID("barrel", 0); + sdet.setPlacement(env_phv); + + sdet.addExtension<DDRec::LayeringExtension>(layeringExtension); + return sdet; } -DECLARE_DETELEMENT(PolyhedraBarrelCalorimeter2,create_detector) +DECLARE_DETELEMENT(PolyhedraBarrelCalorimeter2, create_detector) -- GitLab