diff --git a/Detector/DetCEPCv4/CMakeLists.txt b/Detector/DetCEPCv4/CMakeLists.txt index 19046a6924f3b444505c0389300cc71c283fafeb..03b897aece53d097dcbe979c271d06a39e007021 100644 --- a/Detector/DetCEPCv4/CMakeLists.txt +++ b/Detector/DetCEPCv4/CMakeLists.txt @@ -32,11 +32,13 @@ gaudi_add_module(DetCEPCv4 src/calorimeter/SHcalRpc02_Barrel.cpp src/calorimeter/SHcalRpc01_Endcaps.cpp src/calorimeter/SHcalRpc01_EndcapRing.cpp - src/calorimeter/Yoke05_Barrel.cpp - src/calorimeter/Yoke05_Endcaps.cpp + src/calorimeter/SHcalSc04_Barrel_v04.cpp + src/calorimeter/SHcalSc04_Endcaps_v01.cpp + src/calorimeter/Yoke05_Barrel.cpp + src/calorimeter/Yoke05_Endcaps.cpp src/other/BoxSupport_o1_v01_geo.cpp src/other/TubeSupport_o1_v01_geo.cpp - src/other/SCoil02_geo.cpp + src/other/SCoil02_geo.cpp LINK ${DD4hep_COMPONENT_LIBRARIES} ) diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp new file mode 100644 index 0000000000000000000000000000000000000000..334af303d765b12f008d7eccad8a8f4c02e036ee --- /dev/null +++ b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp @@ -0,0 +1,723 @@ +//==================================================================== +// DD4hep Geometry driver for HcalBarrel +//-------------------------------------------------------------------- +// S.Lu, DESY +// F. Gaede, DESY : v04 : prepare for multi segmentation +// 18.04.2017 - copied from SHcalSc04_Barrel_v01.cpp +// - add optional parameter <subsegmentation key="" value=""/> +// defines the segmentation to be used in reconstruction +//==================================================================== +#include "DD4hep/Printout.h" +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Utilities.h" +#include "DDRec/DetectorData.h" +#include "DDSegmentation/BitField64.h" +#include "DDSegmentation/TiledLayerGridXY.h" +#include "DDSegmentation/Segmentation.h" +#include "DDSegmentation/MultiSegmentation.h" +#include "LcgeoExceptions.h" + +#include <iostream> +#include <vector> + +using namespace std; + +using dd4hep::BUILD_ENVELOPE; +using dd4hep::Box; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::IntersectionSolid; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::Readout; +using dd4hep::Ref_t; +using dd4hep::Rotation3D; +using dd4hep::RotationZ; +using dd4hep::RotationZYX; +using dd4hep::SensitiveDetector; +using dd4hep::Transform3D; +using dd4hep::Trapezoid; +using dd4hep::Tube; +using dd4hep::Volume; +using dd4hep::_toString; + +using dd4hep::rec::LayeredCalorimeterData; + +// After reading in all the necessary parameters. +// To check the radius range and the space for placing the total layers +static bool validateEnvelope(double rInner, double rOuter, double radiatorThickness, double layerThickness, int layerNumber){ + + bool Error = false; + bool Warning = false; + double spaceAllowed = rOuter*cos(M_PI/16.) - rInner; + double spaceNeeded = (radiatorThickness + layerThickness)* layerNumber; + double spaceToleranted = (radiatorThickness + layerThickness)* (layerNumber+1); + double rOuterRecommaned = ( rInner + spaceNeeded )/cos(M_PI/16.); + int layerNumberRecommaned = floor( ( spaceAllowed ) / (radiatorThickness + layerThickness) ); + + + if( spaceNeeded > spaceAllowed ) + { + printout( dd4hep::ERROR, "SHcalSc04_Barrel_v01", " Layer number is more than it can be built! " ) ; + Error = true; + } + else if ( spaceToleranted < spaceAllowed ) + { + printout( dd4hep::WARNING, "SHcalSc04_Barrel_v01", " Layer number is less than it is able to build!" ) ; + Warning = true; + } + else + { + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v01"," has been validated and start to build it." ) ; + Error = false; + Warning = false; + } + + if( Error ) + { + cout<<"\n ============> First Help Documentation <=============== \n" + <<" When you see this message, that means you are crashing the module. \n" + <<" Please take a cup of cafe, and think about what you want to do! \n" + <<" Here are few FirstAid# for you. Please read them carefully. \n" + <<" \n" + <<" ### FirstAid 1: ###\n" + <<" If you want to build HCAL within the rInner and rOuter range, \n" + <<" please reduce the layer number to " << layerNumberRecommaned <<" \n" + <<" with the current layer thickness structure. \n" + <<" \n" + <<" You may redisgn the layer structure and thickness, too. \n" + <<" \n" + <<" ### FirstAid 2: ###\n" + <<" If you want to build HCAL with this layer number and the layer thickness, \n" + <<" you have to update rOuter to "<< rOuterRecommaned*10. <<"*mm \n" + <<" and to inform other subdetector, you need this space for building your design. \n" + <<" \n" + <<" ### FirstAid 3: ###\n" + <<" Do you think that you are looking for another type of HCAL driver? \n" + <<" \n" + <<endl; + throw lcgeo::GeometryException( "SHcalSc04_Barrel: Error: Layer number is more than it can be built!" ) ; + } + else if( Warning ) + { + cout<<"\n ============> First Help Documentation <=============== \n" + <<" When you see this warning message, that means you are changing the module. \n" + <<" Please take a cup of cafe, and think about what you want to do! \n" + <<" Here are few FirstAid# for you. Please read them carefully. \n" + <<" \n" + <<" ### FirstAid 1: ###\n" + <<" If you want to build HCAL within the rInner and rOuter range, \n" + <<" You could build the layer number up to " << layerNumberRecommaned <<" \n" + <<" with the current layer thickness structure. \n" + <<" \n" + <<" You may redisgn the layer structure and thickness, too. \n" + <<" \n" + <<" ### FirstAid 2: ###\n" + <<" If you want to build HCAL with this layer number and the layer thickness, \n" + <<" you could reduce rOuter to "<< rOuterRecommaned*10. <<"*mm \n" + <<" and to reduce the back plate thickness, which you may not need for placing layer. \n" + <<" \n" + <<" ### FirstAid 3: ###\n" + <<" Do you think that you are looking for another type of HCAL driver? \n" + <<" \n" + <<endl; + return Warning; + } + else { return true; } + +} + +static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { + + double boundarySafety = 0.0001; + + xml_det_t x_det = element; + string det_name = x_det.nameStr(); + int det_id = x_det.id(); + DetElement sdet( det_name, det_id ); + + // --- create an envelope volume and position it into the world --------------------- + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, element , sdet ) ; + + dd4hep::xml::setDetectorTypeFlag( element, sdet ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ; + + //----------------------------------------------------------------------------------- + + xml_comp_t x_staves = x_det.staves(); + Material stavesMaterial = theDetector.material(x_staves.materialStr()); + Material air = theDetector.air(); + + PlacedVolume pv; + + sens.setType("calorimeter"); + +//==================================================================== +// +// Read all the constant from ILD_o1_v05.xml +// Use them to build HcalBarrel +// +//==================================================================== + double Hcal_inner_radius = theDetector.constant<double>("Hcal_inner_radius"); + double Hcal_outer_radius = theDetector.constant<double>("Hcal_outer_radius"); + double Hcal_half_length = theDetector.constant<double>("Hcal_half_length"); + int Hcal_inner_symmetry = theDetector.constant<int>("Hcal_inner_symmetry"); + int Hcal_outer_symmetry = 0; // Fixed shape for Tube, and not allow to modify from compact xml. + + double Hcal_radiator_thickness = theDetector.constant<double>("Hcal_radiator_thickness"); + double Hcal_chamber_thickness = theDetector.constant<double>("Hcal_chamber_thickness"); + double Hcal_back_plate_thickness = theDetector.constant<double>("Hcal_back_plate_thickness"); + double Hcal_lateral_plate_thickness = theDetector.constant<double>("Hcal_lateral_structure_thickness"); + double Hcal_stave_gaps = theDetector.constant<double>("Hcal_stave_gaps"); + double Hcal_modules_gap = theDetector.constant<double>("Hcal_modules_gap"); + double Hcal_middle_stave_gaps = theDetector.constant<double>("Hcal_middle_stave_gaps"); + double Hcal_layer_air_gap = theDetector.constant<double>("Hcal_layer_air_gap"); + //double Hcal_cells_size = theDetector.constant<double>("Hcal_cells_size"); + + int Hcal_nlayers = theDetector.constant<int>("Hcal_nlayers"); + + double TPC_outer_radius = theDetector.constant<double>("TPC_outer_radius"); + + double Ecal_outer_radius = theDetector.constant<double>("Ecal_outer_radius"); + + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04", "TPC_outer_radius : %e - Ecal_outer_radius: %e ", TPC_outer_radius , Ecal_outer_radius) ; + + validateEnvelope(Hcal_inner_radius, Hcal_outer_radius, Hcal_radiator_thickness, Hcal_chamber_thickness, Hcal_nlayers); + + Readout readout = sens.readout(); + dd4hep::Segmentation seg = readout.segmentation(); + + dd4hep::DDSegmentation::BitField64 encoder = seg.decoder(); + encoder.setValue(0) ; + + + //fg: this is a bit tricky: we first have to check whether a multi segmentation is used and then, if so, we + // will check the <subsegmentation key="" value=""/> element, for which subsegmentation to use for filling the + // DDRec:LayeredCalorimeterData information. + // Additionally, we need to figure out if there is a TiledLayerGridXY instance defined - + // and in case, there is more than one defined, we need to pick the correct one specified via the + // <subsegmentation key="" value=""/> element. + // This involves a lot of casting: review the API in DD4hep !! + + // check if we have a multi segmentation : + + dd4hep::DDSegmentation::MultiSegmentation* multiSeg = + dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ; + + dd4hep::DDSegmentation::TiledLayerGridXY* tileSeg = 0 ; + + int sensitive_slice_number = -1 ; + + if( multiSeg ){ + + try{ + // check if we have an entry for the subsegmentation to be used + xml_comp_t segxml = x_det.child( _Unicode( subsegmentation ) ) ; + + std::string keyStr = segxml.attr<std::string>( _Unicode(key) ) ; + int keyVal = segxml.attr<int>( _Unicode(value) ) ; + + encoder[ keyStr ] = keyVal ; + + // if we have a multisegmentation that uses the slice as key, we need to know for the + // computation of the layer parameters in LayeredCalorimeterData::Layer below + if( keyStr == "slice" ){ + sensitive_slice_number = keyVal ; + } + + + } catch(const std::runtime_error &) { + throw lcgeo::GeometryException( "SHcalSc04_Barrel: Error: MultiSegmentation specified but no " + " <subsegmentation key="" value=""/> element defined for detector ! " ) ; + } + + // check if we have a TiledLayerGridXY segmentation : + const dd4hep::DDSegmentation::TiledLayerGridXY* ts0 = + dynamic_cast<const dd4hep::DDSegmentation::TiledLayerGridXY*>( &multiSeg->subsegmentation( encoder.getValue() ) ) ; + + tileSeg = const_cast<dd4hep::DDSegmentation::TiledLayerGridXY*>( ts0 ) ; + + if( ! tileSeg ){ // if the current segmentation is not a tileSeg, we see if there is another one + + for( auto s : multiSeg->subSegmentations() ){ + const dd4hep::DDSegmentation::TiledLayerGridXY* ts = + dynamic_cast<const dd4hep::DDSegmentation::TiledLayerGridXY*>( s.segmentation ) ; + + if( ts ) { + tileSeg = const_cast<dd4hep::DDSegmentation::TiledLayerGridXY*>( ts ) ; + break ; + } + } + } + + } else { + + tileSeg = + dynamic_cast< dd4hep::DDSegmentation::TiledLayerGridXY*>( seg.segmentation() ) ; + } + + + + std::vector<double> cellSizeVector = seg.cellDimensions( encoder.getValue() ); //Assume uniform cell sizes, provide dummy cellID + double cell_sizeX = cellSizeVector[0]; + double cell_sizeY = cellSizeVector[1]; + + + //========== fill data for reconstruction ============================ + LayeredCalorimeterData* caloData = new LayeredCalorimeterData ; + caloData->layoutType = LayeredCalorimeterData::BarrelLayout ; + caloData->inner_symmetry = Hcal_inner_symmetry ; + caloData->outer_symmetry = Hcal_outer_symmetry ; + caloData->phi0 = 0 ; // fg: also hardcoded below + + /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm. + caloData->extent[0] = Hcal_inner_radius ; + caloData->extent[1] = Hcal_outer_radius ; + caloData->extent[2] = 0. ; // Barrel zmin is "0" by default. + caloData->extent[3] = Hcal_half_length ; + +//==================================================================== +// +// general calculated parameters +// +//==================================================================== + + double Hcal_total_dim_y = Hcal_nlayers * (Hcal_radiator_thickness + Hcal_chamber_thickness) + + Hcal_back_plate_thickness; + + double Hcal_y_dim1_for_x = Hcal_outer_radius*cos(M_PI/Hcal_inner_symmetry) - Hcal_inner_radius; + double Hcal_bottom_dim_x = 2.*Hcal_inner_radius*tan(M_PI/Hcal_inner_symmetry)- Hcal_stave_gaps; + double Hcal_normal_dim_z = (2 * Hcal_half_length - Hcal_modules_gap)/2.; + + //only the middle has the steel plate. + double Hcal_regular_chamber_dim_z = Hcal_normal_dim_z - Hcal_lateral_plate_thickness; + + //double Hcal_cell_dim_x = Hcal_cells_size; + //double Hcal_cell_dim_z = Hcal_regular_chamber_dim_z / floor (Hcal_regular_chamber_dim_z/Hcal_cell_dim_x); + + +// ========= Create Hcal Barrel stave ==================================== +// It will be the volume for palcing the Hcal Barrel Chamber(i.e. Layers). +// Itself will be placed into the world volume. +// ========================================================================== + + double chambers_y_off_correction = 0.; + + // stave modules shaper parameters + double BHX = (Hcal_bottom_dim_x + Hcal_stave_gaps)/2.; + double THX = (Hcal_total_dim_y + Hcal_inner_radius)*tan(M_PI/Hcal_inner_symmetry); + double YXH = Hcal_total_dim_y / 2.; + double DHZ = (Hcal_normal_dim_z - Hcal_lateral_plate_thickness) / 2.; + + Trapezoid stave_shaper( THX, BHX, DHZ, DHZ, YXH); + + Tube solidCaloTube(0, Hcal_outer_radius, DHZ+boundarySafety); + + RotationZYX mrot(0,0,M_PI/2.); + + Rotation3D mrot3D(mrot); + Position mxyzVec(0,0,(Hcal_inner_radius + Hcal_total_dim_y / 2.)); + Transform3D mtran3D(mrot3D,mxyzVec); + + IntersectionSolid barrelModuleSolid(stave_shaper, solidCaloTube, mtran3D); + + Volume EnvLogHcalModuleBarrel(det_name+"_module",barrelModuleSolid,stavesMaterial); + + EnvLogHcalModuleBarrel.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + + + + + //stave modules lateral plate shaper parameters + double BHX_LP = BHX; + double THX_LP = THX; + double YXH_LP = YXH; + + //build lateral palte here to simulate lateral plate in the middle of barrel. + double DHZ_LP = Hcal_lateral_plate_thickness/2.0; + + Trapezoid stave_shaper_LP(THX_LP, BHX_LP, DHZ_LP, DHZ_LP, YXH_LP); + + Tube solidCaloTube_LP(0, Hcal_outer_radius, DHZ_LP+boundarySafety); + + IntersectionSolid Module_lateral_plate(stave_shaper_LP, solidCaloTube_LP, mtran3D); + + Volume EnvLogHcalModuleBarrel_LP(det_name+"_Module_lateral_plate",Module_lateral_plate,stavesMaterial); + + EnvLogHcalModuleBarrel_LP.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + + +#ifdef SHCALSC04_DEBUG + std::cout<< " ==> Hcal_outer_radius: "<<Hcal_outer_radius <<std::endl; +#endif + + + + + +//==================================================================== +// +// Chambers in the HCAL BARREL +// +//==================================================================== + // Build Layer Chamber fill with air, which include the tolarance space at the two side + // place the slice into the Layer Chamber + // Place the Layer Chamber into the Stave module + // place the Stave module into the asembly Volume + // place the module middle lateral plate into asembly Volume + + double x_length; //dimension of an Hcal barrel layer on the x-axis + double y_height; //dimension of an Hcal barrel layer on the y-axis + double z_width; //dimension of an Hcal barrel layer on the z-axis + x_length = 0.; // Each Layer the x_length has new value. + y_height = Hcal_chamber_thickness / 2.; + z_width = Hcal_regular_chamber_dim_z/2.; + + double xOffset = 0.;//the x_length of a barrel layer is calculated as a + //barrel x-dimension plus (bottom barrel) or minus + //(top barrel) an x-offset, which depends on the angle M_PI/Hcal_inner_symmetry + + double xShift = 0.;//Geant4 draws everything in the barrel related to the + //center of the bottom barrel, so we need to shift the layers to + //the left (or to the right) with the quantity xShift + + + //-------------------- start loop over HCAL layers ---------------------- + + for (int layer_id = 1; layer_id <= (2*Hcal_nlayers); layer_id++) + { + + double TanPiDiv8 = tan(M_PI/Hcal_inner_symmetry); + double x_total = 0.; + double x_halfLength; + x_length = 0.; + + int logical_layer_id = 0; + + if ( (layer_id < Hcal_nlayers) + || (layer_id > Hcal_nlayers && layer_id < (2*Hcal_nlayers)) ) + logical_layer_id = layer_id % Hcal_nlayers; + else if ( (layer_id == Hcal_nlayers) + || (layer_id == 2*Hcal_nlayers) ) logical_layer_id = Hcal_nlayers; + + //---- bottom barrel------------------------------------------------------------ + if( logical_layer_id *(Hcal_radiator_thickness + Hcal_chamber_thickness) + < (Hcal_outer_radius * cos(M_PI/Hcal_inner_symmetry) - Hcal_inner_radius ) ) { + xOffset = (logical_layer_id * Hcal_radiator_thickness + + (logical_layer_id -1) * Hcal_chamber_thickness) * TanPiDiv8; + + x_total = Hcal_bottom_dim_x/2 - Hcal_middle_stave_gaps/2 + xOffset; + x_length = x_total - 2*Hcal_layer_air_gap; + x_halfLength = x_length/2.; + + } else {//----- top barrel ------------------------------------------------- + double y_layerID = logical_layer_id * (Hcal_radiator_thickness + Hcal_chamber_thickness) + Hcal_inner_radius; + double ro_layer = Hcal_outer_radius - Hcal_radiator_thickness; + + x_total = sqrt( ro_layer * ro_layer - y_layerID * y_layerID); + + x_length = x_total - Hcal_middle_stave_gaps; + + x_halfLength = x_length/2.; + + xOffset = (logical_layer_id * Hcal_radiator_thickness + + (logical_layer_id - 1) * Hcal_chamber_thickness - Hcal_y_dim1_for_x) / TanPiDiv8 + + Hcal_chamber_thickness / TanPiDiv8; + + } + + double xAbsShift = (Hcal_middle_stave_gaps/2 + Hcal_layer_air_gap + x_halfLength); + + if (layer_id <= Hcal_nlayers) xShift = - xAbsShift; + else if (layer_id > Hcal_nlayers) xShift = xAbsShift; + + x_length = x_length/2.; + + + //calculate the size of a fractional tile + //-> this sets fract_cell_dim_x + + //double fract_cell_dim_x = 0.; + //this->CalculateFractTileSize(2*x_length, Hcal_cell_dim_x, fract_cell_dim_x); + + //Vector newFractCellDim(fract_cell_dim_x, Hcal_chamber_thickness, Hcal_cell_dim_z); + //theBarrilRegSD->SetFractCellDimPerLayer(layer_id, newFractCellDim); + + encoder["layer"] = logical_layer_id ; + cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); + cell_sizeX = cellSizeVector[0]; + cell_sizeY = cellSizeVector[1]; + + LayeredCalorimeterData::Layer caloLayer ; + caloLayer.cellSize0 = cell_sizeX; + caloLayer.cellSize1 = cell_sizeY; + + + //-------------------------------------------------------------------------------- + // build chamber box, with the calculated dimensions + //------------------------------------------------------------------------------- + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04", " \n Start to build layer chamber - layer_id: %d", layer_id ) ; + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04"," chamber x:y:z: %e:%e:%e", x_length*2., z_width*2. , y_height*2. ); + + //check if x_length (scintillator length) is divisible with x_integerTileSize + if( layer_id <= Hcal_nlayers) { + double fracPart, intPart; + double temp = x_length*2./cell_sizeX; + fracPart = modf(temp, &intPart); + int noOfIntCells = int(temp); + + + if( tileSeg !=0 ){ + + tileSeg->setBoundaryLayerX(x_length); + + if (fracPart == 0){ //divisible + if ( noOfIntCells%2 ) { + if( tileSeg !=0 ) tileSeg->setLayerOffsetX(0); + } + else { + if( tileSeg !=0 ) tileSeg->setLayerOffsetX(1); + } + tileSeg->setFractCellSizeXPerLayer(0); + } + else if (fracPart>0){ + if ( noOfIntCells%2 ) { + if( tileSeg !=0 ) tileSeg->setLayerOffsetX(1); + } + else { + if( tileSeg !=0 ) tileSeg->setLayerOffsetX(0); + } + tileSeg->setFractCellSizeXPerLayer( (fracPart+1.0)/2.0*cell_sizeX ); + } + + if ( (int)( (z_width*2.) / cell_sizeX)%2 ){ + if( tileSeg !=0 ) tileSeg->setLayerOffsetY(0); + } + else { + if( tileSeg !=0 ) tileSeg->setLayerOffsetY(1); + } + + } + } + Box ChamberSolid((x_length + Hcal_layer_air_gap), //x + air gaps at two side, do not need to build air gaps individualy. + z_width, //z attention! + y_height); //y attention! + + string ChamberLogical_name = det_name+_toString(layer_id,"_layer%d"); + + Volume ChamberLogical(ChamberLogical_name, ChamberSolid, air); + + + + double layer_thickness = y_height*2.; + + double nRadiationLengths=0.; + double nInteractionLengths=0.; + double thickness_sum=0; + + nRadiationLengths = Hcal_radiator_thickness/(stavesMaterial.radLength()); + nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength()); + thickness_sum = Hcal_radiator_thickness; + +//==================================================================== +// Create Hcal Barrel Chamber without radiator +// Place into the Hcal Barrel stave, after each radiator +//==================================================================== + xml_coll_t c(x_det,_U(layer)); + xml_comp_t x_layer = c; + string layer_name = det_name+_toString(layer_id,"_layer%d"); + + // Create the slices (sublayers) within the Hcal Barrel Chamber. + double slice_pos_z = layer_thickness/2.; + int slice_number = 0; + + 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 = theDetector.material(x_slice.materialStr()); + DetElement slice(layer_name,_toString(slice_number,"slice%d"),x_det.id()); + + slice_pos_z -= slice_thickness/2.; + + // Slice volume & box + Volume slice_vol(slice_name,Box(x_length,z_width,slice_thickness/2.),slice_material); + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + if ( x_slice.isSensitive() ) { + + slice_vol.setSensitiveDetector(sens); + + // if we have a multisegmentation based on slices, we need to use the correct slice here + if ( sensitive_slice_number<0 || sensitive_slice_number == slice_number ) { + + //Store "inner" quantities + caloLayer.inner_nRadiationLengths = nRadiationLengths; + caloLayer.inner_nInteractionLengths = nInteractionLengths; + caloLayer.inner_thickness = thickness_sum; + //Store scintillator thickness + caloLayer.sensitive_thickness = slice_thickness; + + //Reset counters to measure "outside" quantitites + nRadiationLengths=0.; + nInteractionLengths=0.; + thickness_sum = 0.; + } + } + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + + // Set region, limitset, and vis. + slice_vol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + // slice PlacedVolume + PlacedVolume slice_phv = ChamberLogical.placeVolume(slice_vol,Position(0.,0.,slice_pos_z)); + + slice_phv.addPhysVolID("layer",logical_layer_id).addPhysVolID("slice", slice_number ); + + + if ( x_slice.isSensitive() ) { + int tower_id = (layer_id > Hcal_nlayers)? 1:-1; + slice_phv.addPhysVolID("tower",tower_id); + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04", " logical_layer_id: %d tower_id: %d", logical_layer_id, tower_id ) ; + } + + slice.setPlacement(slice_phv); + // Increment x position for next slice. + slice_pos_z -= slice_thickness/2.; + // Increment slice number. + ++slice_number; + } + + //Store "outer" quantities + caloLayer.outer_nRadiationLengths = nRadiationLengths; + caloLayer.outer_nInteractionLengths = nInteractionLengths; + caloLayer.outer_thickness = thickness_sum; + + +//--------------------------- Chamber Placements ----------------------------------------- + + double chamber_x_offset, chamber_y_offset, chamber_z_offset; + chamber_x_offset = xShift; + + chamber_z_offset = 0; + + + chamber_y_offset = -(-Hcal_total_dim_y/2. + + (logical_layer_id-1) *(Hcal_chamber_thickness + Hcal_radiator_thickness) + + Hcal_radiator_thickness + Hcal_chamber_thickness/2.); + + + pv = EnvLogHcalModuleBarrel.placeVolume(ChamberLogical, + Position(chamber_x_offset, + chamber_z_offset, + chamber_y_offset + chambers_y_off_correction)); + + + + //----------------------------------------------------------------------------------------- + if( layer_id <= Hcal_nlayers ){ // add the first set of layers to the reconstruction data + + caloLayer.distance = Hcal_inner_radius + Hcal_total_dim_y/2.0 - (chamber_y_offset + chambers_y_off_correction) + - caloLayer.inner_thickness ; // Will be added later at "DDMarlinPandora/DDGeometryCreator.cc:226" to get center of sensitive element + + caloLayer.absorberThickness = Hcal_radiator_thickness ; + + caloData->layers.push_back( caloLayer ) ; + } + //----------------------------------------------------------------------------------------- + + + }//end loop over HCAL nlayers; + + if( tileSeg !=0 ){ + // check the offsets directly in the TileSeg ... + std::vector<double> LOX = tileSeg->layerOffsetX(); + std::vector<double> LOY = tileSeg->layerOffsetY(); + + std::stringstream sts ; + sts <<" layerOffsetX(): "; + for (std::vector<double>::const_iterator ix = LOX.begin(); ix != LOX.end(); ++ix) + sts << *ix << ' '; + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04", "%s" , sts.str().c_str() ) ; + sts.clear() ; sts.str("") ; + sts <<" layerOffsetY(): "; + for (std::vector<double>::const_iterator iy = LOY.begin(); iy != LOY.end(); ++iy) + sts << *iy << ' '; + printout( dd4hep::DEBUG, "SHcalSc04_Barrel_v04", "%s" , sts.str().c_str() ) ; + + } + + + +//==================================================================== +// Place HCAL Barrel stave module into the envelope +//==================================================================== + double stave_phi_offset, module_z_offset, lateral_plate_z_offset; + + double Y = Hcal_inner_radius + Hcal_total_dim_y / 2.; + + stave_phi_offset = M_PI/Hcal_inner_symmetry -M_PI/2.; + + + //-------- start loop over HCAL BARREL staves ---------------------------- + + for (int stave_id = 1; + stave_id <=Hcal_inner_symmetry; + stave_id++) + { + module_z_offset = - (Hcal_normal_dim_z + Hcal_modules_gap + Hcal_lateral_plate_thickness)/2.; + lateral_plate_z_offset = - (Hcal_lateral_plate_thickness + Hcal_modules_gap)/2.; + + double phirot = stave_phi_offset; + RotationZYX srot(0,phirot,M_PI*0.5); + Rotation3D srot3D(srot); + + for (int module_id = 1; + module_id <=2; + module_id++) + { + Position sxyzVec(-Y*sin(phirot), Y*cos(phirot), module_z_offset); + Transform3D stran3D(srot3D,sxyzVec); + + // Place Hcal Barrel volume into the envelope volume + pv = envelope.placeVolume(EnvLogHcalModuleBarrel,stran3D); + pv.addPhysVolID("stave",stave_id); + pv.addPhysVolID("module",module_id); + pv.addPhysVolID("system",det_id); + + const int staveCounter = (stave_id-1)*2+module_id-1; + DetElement stave(sdet, _toString(staveCounter,"stave%d"), staveCounter ); + stave.setPlacement(pv); + + Position xyzVec_LP(-Y*sin(phirot), Y*cos(phirot),lateral_plate_z_offset); + Transform3D tran3D_LP(srot3D,xyzVec_LP); + pv = envelope.placeVolume(EnvLogHcalModuleBarrel_LP,tran3D_LP); + + module_z_offset = - module_z_offset; + lateral_plate_z_offset = - lateral_plate_z_offset; + } + + + stave_phi_offset -= M_PI*2.0/Hcal_inner_symmetry; + } //-------- end loop over HCAL BARREL staves ---------------------------- + + + sdet.addExtension< LayeredCalorimeterData >( caloData ) ; + + + return sdet; + +} + +DECLARE_DETELEMENT(SHcalSc04_Barrel_v04, create_detector) diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b074089bdb71a1938347b3cdd9008d3b598a2ba --- /dev/null +++ b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp @@ -0,0 +1,498 @@ +//==================================================================== +// AIDA Detector description implementation +// for LDC AHCAL Endcap +//-------------------------------------------------------------------- +// +// Author : S.Lu +// F. Gaede, DESY : v01 : prepare for multi segmentation +// 18.04.2017 - copied from SHcalSc04_Barrel_v01.cpp +// - add optional parameter <subsegmentation key="" value=""/> +// defines the segmentation to be used in reconstruction +// +// Basic idea: +// 1. Create the Hcal Endcap module envelope (16 modules). +// Note: with default material Steel235. +// +// 2. Create the Hcal Endcap Chamber(i.e. Layer) for each module. +// Create the Layer with slices (Polystyrene,Cu,FR4,air). +// Place each slice into the chamber with the right position, +// And registry the IDs for slice +// +// 3. Place the same Layer into the endcap module envelope. +// It will be repeated repeat 48 times. +// And registry the IDs for layer, and endcapID. +// +// 4. Place the endcap module into the world volume, +// with the right position and rotation. +// And registry the IDs for stave,module and endcapID. +// +// 5. Customer material FR4 and Steel235 defined in materials.xml +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DetType.h" +#include "XML/Layering.h" +#include "XML/Utilities.h" +#include "DDRec/DetectorData.h" +#include "DDSegmentation/BitField64.h" +#include "DDSegmentation/Segmentation.h" +#include "DDSegmentation/MultiSegmentation.h" +#include "LcgeoExceptions.h" + +using namespace std; + +using dd4hep::BUILD_ENVELOPE; +using dd4hep::BitField64; +using dd4hep::Box; +using dd4hep::DetElement; +using dd4hep::DetType; +using dd4hep::Detector; +using dd4hep::Layering; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::Readout; +using dd4hep::Ref_t; +using dd4hep::RotationX; +using dd4hep::Segmentation; +using dd4hep::SensitiveDetector; +using dd4hep::Transform3D; +using dd4hep::Translation3D; +using dd4hep::Volume; +using dd4hep::_toString; + +using dd4hep::rec::LayeredCalorimeterData; + + +static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { + xml_det_t x_det = element; + Layering layering(x_det); + xml_dim_t dim = x_det.dimensions(); + string det_name = x_det.nameStr(); + + Material air = theDetector.air(); + Material stavesMaterial = theDetector.material(x_det.materialStr()); + int numSides = dim.numsides(); + + int det_id = x_det.id(); + + DetElement sdet(det_name,det_id); + + PlacedVolume pVol; + + // --- create an envelope volume and position it into the world --------------------- + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, element , sdet ) ; + + sdet.setTypeFlag( DetType::CALORIMETER | DetType::ENDCAP | DetType::HADRONIC ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ; + //----------------------------------------------------------------------------------- + + sens.setType("calorimeter"); + + DetElement stave_det("module0stave0",det_id); + + // The way to reaad constant from XML/Detector file. + double Hcal_radiator_thickness = theDetector.constant<double>("Hcal_radiator_thickness"); + double Hcal_endcap_lateral_structure_thickness = theDetector.constant<double>("Hcal_endcap_lateral_structure_thickness"); + double Hcal_endcap_layer_air_gap = theDetector.constant<double>("Hcal_endcap_layer_air_gap"); + + //double Hcal_cells_size = theDetector.constant<double>("Hcal_cells_size"); + double HcalEndcap_inner_radius = theDetector.constant<double>("Hcal_endcap_inner_radius"); + double HcalEndcap_outer_radius = theDetector.constant<double>("Hcal_endcap_outer_radius"); + double HcalEndcap_min_z = theDetector.constant<double>("Hcal_endcap_zmin"); + double HcalEndcap_max_z = theDetector.constant<double>("Hcal_endcap_zmax"); + + double Hcal_steel_cassette_thickness = theDetector.constant<double>("Hcal_steel_cassette_thickness"); + double HcalServices_outer_FR4_thickness = theDetector.constant<double>("Hcal_services_outer_FR4_thickness"); + double HcalServices_outer_Cu_thickness = theDetector.constant<double>("Hcal_services_outer_Cu_thickness"); + double Hcal_endcap_services_module_width = theDetector.constant<double>("Hcal_endcap_services_module_width"); + + Material stainless_steel = theDetector.material("stainless_steel"); + Material PCB = theDetector.material("PCB"); + Material copper = theDetector.material("Cu"); + + std::cout <<"\n HcalEndcap_inner_radius = " + <<HcalEndcap_inner_radius/dd4hep::mm <<" mm" + <<"\n HcalEndcap_outer_radius = " + <<HcalEndcap_outer_radius/dd4hep::mm <<" mm" + <<"\n HcalEndcap_min_z = " + <<HcalEndcap_min_z/dd4hep::mm <<" mm" + <<"\n HcalEndcap_max_z = " + <<HcalEndcap_max_z/dd4hep::mm <<" mm" + <<std::endl; + + Readout readout = sens.readout(); + Segmentation seg = readout.segmentation(); + + + BitField64 encoder = seg.decoder(); + encoder.setValue(0) ; + + // we first have to check whether a multi segmentation is used and then, if so, we + // will check the <subsegmentation key="" value=""/> element, for which subsegmentation to use for filling the + // DDRec:LayeredCalorimeterData information. + + // check if we have a multi segmentation : + dd4hep::DDSegmentation::MultiSegmentation* multiSeg = + dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ; + + int sensitive_slice_number = -1 ; + + if( multiSeg ){ + + try{ + // check if we have an entry for the subsegmentation to be used + xml_comp_t segxml = x_det.child( _Unicode( subsegmentation ) ) ; + + std::string keyStr = segxml.attr<std::string>( _Unicode(key) ) ; + int keyVal = segxml.attr<int>( _Unicode(value) ) ; + + encoder[ keyStr ] = keyVal ; + + // if we have a multisegmentation that uses the slice as key, we need to know for the + // computation of the layer parameters in LayeredCalorimeterData::Layer below + if( keyStr == "slice" ){ + sensitive_slice_number = keyVal ; + } + + } catch(const std::runtime_error &) { + throw lcgeo::GeometryException( "SHcalSc04_Endcaps_v01: Error: MultiSegmentation specified but no " + " <subsegmentation key="" value=""/> element defined for detector ! " ) ; + } + } + + //========== fill data for reconstruction ============================ + LayeredCalorimeterData* caloData = new LayeredCalorimeterData ; + caloData->layoutType = LayeredCalorimeterData::EndcapLayout ; + caloData->inner_symmetry = 4 ; // hard code cernter box hole + caloData->outer_symmetry = 0 ; // outer tube, or 8 for Octagun + caloData->phi0 = 0 ; + + /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm. + caloData->extent[0] = HcalEndcap_inner_radius ; + caloData->extent[1] = HcalEndcap_outer_radius ; + caloData->extent[2] = HcalEndcap_min_z ; + caloData->extent[3] = HcalEndcap_max_z ; + + + int endcapID = 0; + for(xml_coll_t c(x_det.child(_U(dimensions)),_U(dimensions)); c; ++c) + { + xml_comp_t l(c); + + double dim_x = l.attr<double>(_Unicode(dim_x)); + double dim_y = l.attr<double>(_Unicode(dim_y)); + double dim_z = l.attr<double>(_Unicode(dim_z)); + double pos_y = l.attr<double>(_Unicode(y_offset)); + + // Hcal Endcap module shape + double box_half_x= dim_x/2.0; // module width, all are same + double box_half_y= dim_y/2.0; // module length, changing + double box_half_z= dim_z/2.0; // total thickness, all are same + + double x_offset = box_half_x*numSides-box_half_x*endcapID*2.0-box_half_x; + double y_offset = pos_y; + + Box EndcapModule(box_half_x,box_half_y,box_half_z); + + // define the name of each endcap Module + string envelopeVol_name = det_name+_toString(endcapID,"_EndcapModule%d"); + + Volume envelopeVol(envelopeVol_name,EndcapModule,stavesMaterial); + + // Set envelope volume attributes. + envelopeVol.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + + double FEE_half_x = box_half_x-Hcal_endcap_services_module_width/2.0; + double FEE_half_y = Hcal_endcap_services_module_width/2.0; + double FEE_half_z = box_half_z; + + Box FEEBox(FEE_half_x,FEE_half_y,FEE_half_z); + Volume FEEModule("Hcal_endcap_FEE",FEEBox,air); + + double FEELayer_thickness = Hcal_steel_cassette_thickness + HcalServices_outer_FR4_thickness + HcalServices_outer_Cu_thickness; + Box FEELayerBox(FEE_half_x,FEE_half_y,FEELayer_thickness/2.0); + Volume FEELayer("FEELayer",FEELayerBox,air); + + Box FEELayerSteelBox(FEE_half_x,FEE_half_y,Hcal_steel_cassette_thickness/2.0); + Volume FEELayerSteel("FEELayerSteel",FEELayerSteelBox,stainless_steel); + pVol = FEELayer.placeVolume(FEELayerSteel, + Position(0, + 0, + (-FEELayer_thickness/2.0 + +Hcal_steel_cassette_thickness/2.0))); + + Box FEELayerFR4Box(FEE_half_x,FEE_half_y,HcalServices_outer_FR4_thickness/2.0); + Volume FEELayerFR4("FEELayerFR4",FEELayerFR4Box,PCB); + pVol = FEELayer.placeVolume(FEELayerFR4, + Position(0, + 0, + (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness + +HcalServices_outer_FR4_thickness/2.0))); + + Box FEELayerCuBox(FEE_half_x,FEE_half_y,HcalServices_outer_Cu_thickness/2.0); + Volume FEELayerCu("FEELayerCu",FEELayerCuBox,copper); + pVol = FEELayer.placeVolume(FEELayerCu, + Position(0, + 0, + (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness+HcalServices_outer_FR4_thickness +HcalServices_outer_Cu_thickness/2.0))); + + + // ========= Create Hcal Chamber (i.e. Layers) ============================== + // It will be the sub volume for placing the slices. + // Itself will be placed into the Hcal Endcap modules envelope. + // ========================================================================== + + // create Layer (air) and place the slices (Polystyrene,Cu,FR4,air) into it. + // place the Layer into the Hcal Endcap Modules envelope (stavesMaterial). + + // First Hcal Chamber position, start after first radiator + double layer_pos_z = - box_half_z + Hcal_radiator_thickness; + + // Create Hcal Endcap Chamber without radiator + // Place into the Hcal Encap module envelope, after each radiator + int layer_num = 1; + for(xml_coll_t m(x_det,_U(layer)); m; ++m) { + xml_comp_t x_layer = m; + int repeat = x_layer.repeat(); // Get number of layers. + + double layer_thickness = layering.layer(layer_num)->thickness(); + string layer_name = envelopeVol_name+"_layer"; + DetElement layer(stave_det,layer_name,det_id); + + // Active Layer box & volume + double active_layer_dim_x = box_half_x - Hcal_endcap_lateral_structure_thickness - Hcal_endcap_layer_air_gap; + double active_layer_dim_y = box_half_y; + double active_layer_dim_z = layer_thickness/2.0; + + // Build chamber including air gap + // The Layer will be filled with slices, + Volume layer_vol(layer_name, Box((active_layer_dim_x + Hcal_endcap_layer_air_gap), + active_layer_dim_y,active_layer_dim_z), air); + + + + encoder["layer"] = layer_num ; + std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); + + LayeredCalorimeterData::Layer caloLayer ; + caloLayer.cellSize0 = cellSizeVector[0]; + caloLayer.cellSize1 = cellSizeVector[1]; + + // ========= Create sublayer slices ========================================= + // Create and place the slices into Layer + // ========================================================================== + + // Create the slices (sublayers) within the Hcal Chamber. + double slice_pos_z = -(layer_thickness / 2.0); + int slice_number = 0; + + double nRadiationLengths=0.; + double nInteractionLengths=0.; + double thickness_sum=0; + + nRadiationLengths = Hcal_radiator_thickness/(stavesMaterial.radLength()); + nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength()); + thickness_sum = Hcal_radiator_thickness; + + 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 = theDetector.material(x_slice.materialStr()); + DetElement slice(layer,_toString(slice_number,"slice%d"),det_id); + + slice_pos_z += slice_thickness / 2.0; + + // Slice volume & box + Volume slice_vol(slice_name,Box(active_layer_dim_x,active_layer_dim_y,slice_thickness/2.0),slice_material); + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + + if ( x_slice.isSensitive() ) { + + slice_vol.setSensitiveDetector(sens); + + // if we have a multisegmentation based on slices, we need to use the correct slice here + if ( sensitive_slice_number<0 || sensitive_slice_number == slice_number ) { + + //Store "inner" quantities + caloLayer.inner_nRadiationLengths = nRadiationLengths; + caloLayer.inner_nInteractionLengths = nInteractionLengths; + caloLayer.inner_thickness = thickness_sum; + //Store scintillator thickness + caloLayer.sensitive_thickness = slice_thickness; + + //Reset counters to measure "outside" quantitites + nRadiationLengths=0.; + nInteractionLengths=0.; + thickness_sum = 0.; + } + } + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + // Set region, limitset, and vis. + slice_vol.setAttributes(theDetector,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.0; + // Increment slice number. + ++slice_number; + } + // Set region, limitset, and vis. + layer_vol.setAttributes(theDetector,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + + //Store "outer" quantities + caloLayer.outer_nRadiationLengths = nRadiationLengths; + caloLayer.outer_nInteractionLengths = nInteractionLengths; + caloLayer.outer_thickness = thickness_sum; + + // ========= Place the Layer (i.e. Chamber) ================================= + // Place the Layer into the Hcal Endcap module envelope. + // with the right position and rotation. + // Registry the IDs (layer, stave, module). + // Place the same layer 48 times into Endcap module + // ========================================================================== + + for (int j = 0; j < repeat; j++) { + + // Layer position in y within the Endcap Modules. + layer_pos_z += layer_thickness / 2.0; + + PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol, + Position(0,0,layer_pos_z)); + // registry the ID of Layer, stave and module + layer_phv.addPhysVolID("layer",layer_num); + + // then setPlacement for it. + layer.setPlacement(layer_phv); + + pVol = FEEModule.placeVolume(FEELayer, + Position(0,0,layer_pos_z)); + //----------------------------------------------------------------------------------------- + if ( caloData->layers.size() < (unsigned int)repeat ) { + + caloLayer.distance = HcalEndcap_min_z + box_half_z + layer_pos_z + - caloLayer.inner_thickness ; // Will be added later at "DDMarlinPandora/DDGeometryCreator.cc:226" to get center of sensitive element + caloLayer.absorberThickness = Hcal_radiator_thickness ; + + caloData->layers.push_back( caloLayer ) ; + } + //----------------------------------------------------------------------------------------- + + + // ===== Prepare for next layer (i.e. next Chamber) ========================= + // Prepare the chamber placement position and the chamber dimension + // ========================================================================== + + // Increment the layer_pos_y + // Place Hcal Chamber after each radiator + layer_pos_z += layer_thickness / 2.0; + layer_pos_z += Hcal_radiator_thickness; + ++layer_num; + } + + + } + + + // =========== Place Hcal Endcap envelope =================================== + // Finally place the Hcal Endcap envelope into the world volume. + // Registry the stave(up/down), module(left/right) and endcapID. + // ========================================================================== + + // Acording to the number of staves and modules, + // Place the same Hcal Endcap module volume into the world volume + // with the right position and rotation. + for(int stave_num=0;stave_num<2;stave_num++){ + + double EndcapModule_pos_x = 0; + double EndcapModule_pos_y = 0; + double EndcapModule_pos_z = 0; + double rot_EM = 0; + + double EndcapModule_center_pos_z = HcalEndcap_min_z + box_half_z; + + double FEEModule_pos_x = 0; + double FEEModule_pos_y = 0; + double FEEModule_pos_z = 0; + double FEEModule_center_pos_z = HcalEndcap_min_z + box_half_z; + + switch (stave_num) + { + case 0 : + EndcapModule_pos_x = x_offset; + EndcapModule_pos_y = y_offset; + FEEModule_pos_x = x_offset; + FEEModule_pos_y = y_offset + box_half_y + Hcal_endcap_services_module_width/2.0; + break; + case 1 : + EndcapModule_pos_x = -x_offset; + EndcapModule_pos_y = -y_offset; + FEEModule_pos_x = -x_offset; + FEEModule_pos_y = -y_offset - box_half_y - Hcal_endcap_services_module_width/2.0; + break; + } + + for(int module_num=0;module_num<2;module_num++) { + + int module_id = (module_num==0)? 0:6; + + rot_EM = (module_id==0)?M_PI:0; + + EndcapModule_pos_z = (module_id==0)? -EndcapModule_center_pos_z:EndcapModule_center_pos_z; + + PlacedVolume env_phv = envelope.placeVolume(envelopeVol, + Transform3D(RotationX(rot_EM), + Translation3D(EndcapModule_pos_x, + EndcapModule_pos_y, + EndcapModule_pos_z))); + env_phv.addPhysVolID("tower",endcapID); + env_phv.addPhysVolID("stave",stave_num); // y: up /down + env_phv.addPhysVolID("module",module_id); // z: -/+ 0/6 + env_phv.addPhysVolID("system",det_id); + + FEEModule_pos_z = (module_id==0)? -FEEModule_center_pos_z:FEEModule_center_pos_z; + + if (!(endcapID==0)) + env_phv = envelope.placeVolume(FEEModule, + Transform3D(RotationX(rot_EM), + Translation3D(FEEModule_pos_x, + FEEModule_pos_y, + FEEModule_pos_z))); + + + DetElement sd = (module_num==0&&stave_num==0) ? stave_det : stave_det.clone(_toString(module_id,"module%d")+_toString(stave_num,"stave%d")); + sd.setPlacement(env_phv); + + } + + } + + endcapID++; + + } + + sdet.addExtension< LayeredCalorimeterData >( caloData ) ; + + return sdet; +} + + + + +DECLARE_DETELEMENT(SHcalSc04_Endcaps_v01, create_detector) diff --git a/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..32810ce1c0da9fdf6f602daa770d2815778ddb37 --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml @@ -0,0 +1,71 @@ +<!-- comment>Calorimeters</comment --> + +<lccdd> + <define> + <constant name="Hcal_cell_size" value="10*mm"/> + <constant name="Hcal_inner_radius" value="Hcal_barrel_inner_radius"/> + <constant name="Hcal_half_length" value="Hcal_barrel_half_length"/> + <constant name="Hcal_inner_symmetry" value="Hcal_barrel_symmetry"/> + <constant name="Hcal_nlayers" value="38"/> + <constant name="Hcal_radiator_thickness" value="20.0*mm"/> + <constant name="Hcal_chamber_thickness" value="6.5*mm"/> + <constant name="Hcal_back_plate_thickness" value="15*mm"/> + <constant name="Hcal_lateral_structure_thickness" value="10*mm"/> + <constant name="Hcal_stave_gaps" value="0*mm"/> + <constant name="Hcal_middle_stave_gaps" value="0*mm"/> + <constant name="Hcal_modules_gap" value="2*mm"/> + <constant name="Hcal_layer_air_gap" value="0*mm"/> + <constant name="HcalSD_glass_anode_thickness" value="0.7*mm"/> + <constant name="HcalSD_sensitive_gas_gap" value="1.2*mm"/> + <constant name="HcalSD_glass_cathode_thickness" value="1.1*mm"/> + <constant name="Hcal_scintillator_thickness" value="3.0*mm"/> + <constant name="Ecal_outer_radius" value="Ecal_barrel_outer_radius"/> + <constant name="Hcal_readout_segmentation_slice" value="3"/> + </define> + <detectors> + <detector name="HcalBarrel" type="SHcalSc04_Barrel_v04" id="DetID_HCAL" readout="HcalBarrelCollection" vis="GreenVis" insideTrackingVolume="false" > + <comment>Hadron Calorimeter Barrel</comment> + + <envelope vis="ILD_HCALVis"> + <shape type="BooleanShape" operation="Subtraction" material="Air" > + <shape type="Cone" rmin1="0.0" rmax1="Hcal_outer_radius + env_safety" rmin2="0.0" rmax2="Hcal_outer_radius + env_safety" z="Hcal_half_length + env_safety/2.0"/> + <shape type="PolyhedraRegular" numsides="Hcal_inner_symmetry" rmin="0.0" + rmax="Hcal_inner_radius - env_safety" dz="2*(Hcal_half_length + env_safety)"/> + </shape> + <rotation x="0" y="0" z="90*deg-180*deg/Hcal_inner_symmetry"/> + </envelope> + + <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " /> + + <staves material = "Steel235" vis="BlueVis"/> + + + <!-- select which subsegmentation will be used to fill the DDRec:LayeredCalorimeterData cell dimensions --> + <subsegmentation key="slice" value="Hcal_readout_segmentation_slice"/> + + <layer repeat="Hcal_nlayers" vis="SeeThrough"> + <slice material="FloatGlass" thickness="HcalSD_glass_anode_thickness" vis="Invisible"/> + <slice material="RPCGAS2" thickness="HcalSD_sensitive_gas_gap" sensitive="yes" limits="cal_limits" vis="YellowVis"/> + <slice material="FloatGlass" thickness="HcalSD_glass_cathode_thickness" vis="Invisible"/> + <slice material="G4_POLYSTYRENE" thickness = "Hcal_scintillator_thickness" sensitive = "yes" limits="cal_limits" vis="CyanVis" /> + <slice material="Air" thickness="Hcal_chamber_thickness - ( HcalSD_glass_anode_thickness + HcalSD_sensitive_gas_gap + HcalSD_glass_cathode_thickness + Hcal_scintillator_thickness)" vis="Invisible" /> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="HcalBarrelCollection"> + <segmentation type="MultiSegmentation" key="slice"> + <segmentation name="RPCgrid" type="CartesianGridXY" key_value="1" grid_size_x="Hcal_cell_size" grid_size_y="Hcal_cell_size" /> + <segmentation name="Scigrid" type="TiledLayerGridXY" key_value="3" grid_size_x="3" grid_size_y="3.03248"/> + </segmentation> + <hits_collections> + <hits_collection name="HCalBarrelRPCHits" key="slice" key_value="1"/> + <hits_collection name="HcalBarrelRegCollection" key="slice" key_value="3"/> + </hits_collections> + <id>system:5,module:3,stave:4,tower:5,layer:6,slice:4,x:32:-16,y:-16</id> + </readout> + </readouts> + + +</lccdd> diff --git a/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b11b773d72d530ae92aaf640de0b6e8d705d168 --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml @@ -0,0 +1,90 @@ +<lccdd> + <define> + <constant name="SDHCal_cell_size" value="10*mm"/> + <constant name="AHCal_cell_size" value="10*mm"/> + <constant name="Hcal_endcap_lateral_structure_thickness" value="5.0*mm"/> + <constant name="Hcal_endcap_layer_air_gap" value="2.5*mm"/> + <constant name="Hcal_steel_cassette_thickness" value="0.5*mm"/> + <constant name="Hcal_services_outer_FR4_thickness" value="2.8*mm"/> + <constant name="Hcal_services_outer_Cu_thickness" value="0.4*mm"/> + <constant name="Hcal_endcap_services_module_width" value="100.0*mm"/> + <constant name="Hcal_endcap_nlayers" value="40"/> + <constant name="Hcal_endcap_env_thickness" value="Hcal_endcap_zmax-Hcal_endcap_zmin"/> + <constant name="Hcal_x_modul" value="12"/> + <constant name="Hcal_x_width" value="Hcal_endcap_inner_radius*2/2"/><!--350--> + <constant name="Hcal_y_height" value="Hcal_x_width*Hcal_x_modul/2"/><!--2100--> + <constant name="Hcal_hole_height" value="Hcal_endcap_inner_radius"/> + <constant name="Hcal_r_max" value="Hcal_y_height/cos(pi/Hcal_endcap_symmetry)"/><!--2174.08--> + <constant name="Hcal_x_top" value="Hcal_y_height*tan(pi/Hcal_endcap_symmetry)"/> <!--562.69--> + <constant name="Hcal_x_point" value="(Hcal_y_height+Hcal_x_top*tan(2*pi/Hcal_endcap_symmetry))/(1+tan(2*pi/Hcal_endcap_symmetry))"/><!--1537.30--> + <constant name="Hcal_y5" value="Hcal_y_height-(Hcal_x_width*2-Hcal_x_top)*tan(2*pi/Hcal_endcap_symmetry)"/> + <constant name="Hcal_y4" value="Hcal_y5-Hcal_x_width*tan(2*pi/Hcal_endcap_symmetry)"/> + <constant name="Hcal_y3" value="Hcal_y4-Hcal_x_width*tan(2*pi/Hcal_endcap_symmetry)"/> + <constant name="Hcal_y2" value="Hcal_x_top+Hcal_x_width/tan(2*pi/Hcal_endcap_symmetry)"/> + + </define> + <detectors> + <detector id="DetID_HCAL_ENDCAP" name="HcalEndcap" type="SHcalSc04_Endcaps_v01" readout="HcalEndcapsReadout" vis="GreenVis" calorimeterType="HAD_ENDCAP"> + <comment>Hadron Calorimeter Endcap</comment> + + <envelope vis="ILD_HCALVis"> + <shape type="BooleanShape" operation="Subtraction" material="Air"><!--2. create center box hole --> + <shape type="BooleanShape" operation="Subtraction" material="Air"><!--1. create Endcaps envelope --> + <shape type="Tube" rmin="0.0" rmax="Solenoid_inner_radius" dz="Hcal_endcap_zmax + env_safety"/> + <shape type="Tube" rmin="0.0" rmax="Solenoid_inner_radius" dz="Hcal_endcap_zmin - env_safety"/> + </shape> + <shape type="Box" dx="Hcal_endcap_inner_radius - env_safety" dy="Hcal_endcap_inner_radius - env_safety" + dz="Hcal_endcap_zmax + 2.0*env_safety"/> + </shape> + <rotation x="0" y="0" z="0"/> + </envelope> + + <type_flags type=" DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC " /> + + <material name="Steel235"/><!-- radiator and the thickness has been defined in the main xml file--> + + <dimensions numsides="Hcal_x_modul" > + <dimensions id="1" y_offset="Hcal_x_top/2" dim_x="Hcal_hole_height" dim_y="Hcal_x_top" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="2" y_offset="Hcal_y2/2" dim_x="Hcal_hole_height" dim_y="Hcal_y2" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="3" y_offset="Hcal_y3/2" dim_x="Hcal_hole_height" dim_y="Hcal_y3" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="4" y_offset="Hcal_y4/2" dim_x="Hcal_hole_height" dim_y="Hcal_y4" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="5" y_offset="Hcal_y5/2" dim_x="Hcal_hole_height" dim_y="Hcal_y5" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="6" y_offset="Hcal_y_height/2+Hcal_hole_height/2" dim_x="Hcal_hole_height" dim_y="Hcal_y_height-Hcal_hole_height" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="7" y_offset="Hcal_y_height/2+Hcal_hole_height/2" dim_x="Hcal_hole_height" dim_y="Hcal_y_height-Hcal_hole_height" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="8" y_offset="Hcal_y5/2" dim_x="Hcal_hole_height" dim_y="Hcal_y5" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="9" y_offset="Hcal_y4/2" dim_x="Hcal_hole_height" dim_y="Hcal_y4" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="10" y_offset="Hcal_y3/2" dim_x="Hcal_hole_height" dim_y="Hcal_y3" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="11" y_offset="Hcal_y2/2" dim_x="Hcal_hole_height" dim_y="Hcal_y2" dim_z="Hcal_endcap_env_thickness"/> + <dimensions id="12" y_offset="Hcal_x_top/2" dim_x="Hcal_hole_height" dim_y="Hcal_x_top" dim_z="Hcal_endcap_env_thickness"/> + </dimensions> + + <!-- select which subsegmentation will be used to fill the DDRec:LayeredCalorimeterData cell dimensions --> + <subsegmentation key="slice" value="Hcal_readout_segmentation_slice"/> + + <layer repeat="Hcal_endcap_nlayers" vis="SeeThrough"> + <slice material="FloatGlass" thickness="HcalSD_glass_anode_thickness" vis="Invisible"/> + <slice material="RPCGAS2" thickness="HcalSD_sensitive_gas_gap" sensitive="yes" limits="cal_limits" vis="YellowVis"/> + <slice material="FloatGlass" thickness="HcalSD_glass_cathode_thickness" vis="Invisible"/> + <slice material="G4_POLYSTYRENE" thickness = "Hcal_scintillator_thickness" sensitive = "yes" limits="cal_limits" vis="CyanVis" /> + <slice material="Air" thickness="Hcal_chamber_thickness - ( HcalSD_glass_anode_thickness + HcalSD_sensitive_gas_gap + HcalSD_glass_cathode_thickness + Hcal_scintillator_thickness)" vis="Invisible" /> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="HcalEndcapsReadout"> + <segmentation type="MultiSegmentation" key="slice"> + <segmentation name="RPCgrid" type="CartesianGridXY" key_value="1" grid_size_x="SDHCal_cell_size" grid_size_y="SDHCal_cell_size" offset_x="SDHCal_cell_size/2.0" offset_y="SDHCal_cell_size/2.0" /> + <segmentation name="Scigrid" type="CartesianGridXY" key_value="3" grid_size_x="AHCal_cell_size" grid_size_y="AHCal_cell_size" offset_x="AHCal_cell_size/2.0" offset_y="AHCal_cell_size/2.0" /> + </segmentation> + <hits_collections> + <hits_collection name="HCalEndcapRPCHits" key="slice" key_value="1"/> + <hits_collection name="HcalEndcapsCollection" key="slice" key_value="3"/> + </hits_collections> + <id>system:5,module:3,stave:3,tower:5,layer:6,slice:4,x:32:-16,y:-16</id> + </readout> + </readouts> + + +</lccdd> + diff --git a/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml b/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml new file mode 100644 index 0000000000000000000000000000000000000000..42edeebec1c972c0eb4cfa5665c02759a332e711 --- /dev/null +++ b/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + <info name="StandaloneEcalRotCrystal" + title="CepC standalone calorimeter with rotated crystal" + author="C.D.Fu" + url="http://cepc.ihep.ac.cn" + status="developing" + version="v01"> + <comment>CepC detector simulation models used for detector study </comment> + </info> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="../CRD_common_v01/materials.xml"/> + </includes> + + <define> + <constant name="world_size" value="6*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + + <include ref="${DD4hepINSTALL}/DDDetectors/compact/detector_types.xml"/> + </define> + + <include ref="./Dimensions_v01_01.xml"/> + + <!--include ref="../CRD_common_v01/Coil_Simple_v01_01.xml"/--> + <include ref="../CRD_common_v01/SHcalSc04_Barrel_v04_01.xml"/> + <include ref="../CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml"/> + + <fields> + <field name="InnerSolenoid" type="solenoid" + inner_field="Field_nominal_value" + outer_field="0" + zmax="SolenoidCoil_half_length" + inner_radius="SolenoidCoil_center_radius" + outer_radius="Solenoid_outer_radius"> + </field> + <field name="OuterSolenoid" type="solenoid" + inner_field="0" + outer_field="Field_outer_nominal_value" + zmax="SolenoidCoil_half_length" + inner_radius="Solenoid_outer_radius" + outer_radius="Yoke_barrel_inner_radius"> + </field> + </fields> + +</lccdd> diff --git a/Detector/DetCRD/scripts/CRD-Sim.py b/Detector/DetCRD/scripts/CRD-Sim.py index a4ad74c40c73b4b30ba43e51560e7d755a9b6d77..0e734b785f0c6442b320bc75e43c3d10472bc8a5 100644 --- a/Detector/DetCRD/scripts/CRD-Sim.py +++ b/Detector/DetCRD/scripts/CRD-Sim.py @@ -89,6 +89,23 @@ detsimalg.AnaElems = [ ] detsimalg.RootDetElem = "WorldDetElemTool" +dedxoption = "BetheBlochEquationDedxSimTool" +from Configurables import DriftChamberSensDetTool +dc_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool") +dc_sensdettool.DedxSimTool = dedxoption + +from Configurables import DummyDedxSimTool +from Configurables import BetheBlochEquationDedxSimTool + +if dedxoption == "DummyDedxSimTool": + dedx_simtool = DummyDedxSimTool("DummyDedxSimTool") +elif dedxoption == "BetheBlochEquationDedxSimTool": + dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool") + dedx_simtool.material_Z = 2 + dedx_simtool.material_A = 4 + dedx_simtool.scale = 10 + dedx_simtool.resolution = 0.0001 + # output from Configurables import PodioOutput out = PodioOutput("outputalg") diff --git a/Detector/DetCRD/scripts/CRD_o1_v01-SimRec.py b/Detector/DetCRD/scripts/CRD_o1_v01-SimRec.py index 1810a5749abca5cab4561466e90b32ddb05ef4ab..19836013be8fcc3b1dcbcd6993473de64b1a0ba5 100644 --- a/Detector/DetCRD/scripts/CRD_o1_v01-SimRec.py +++ b/Detector/DetCRD/scripts/CRD_o1_v01-SimRec.py @@ -84,6 +84,23 @@ detsimalg.AnaElems = [ ] detsimalg.RootDetElem = "WorldDetElemTool" +dedxoption = "BetheBlochEquationDedxSimTool" +from Configurables import DriftChamberSensDetTool +dc_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool") +dc_sensdettool.DedxSimTool = dedxoption + +from Configurables import DummyDedxSimTool +from Configurables import BetheBlochEquationDedxSimTool + +if dedxoption == "DummyDedxSimTool": + dedx_simtool = DummyDedxSimTool("DummyDedxSimTool") +elif dedxoption == "BetheBlochEquationDedxSimTool": + dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool") + dedx_simtool.material_Z = 2 + dedx_simtool.material_A = 4 + dedx_simtool.scale = 10 + dedx_simtool.resolution = 0.0001 + from Configurables import MarlinEvtSeeder evtseeder = MarlinEvtSeeder("EventSeeder") diff --git a/Detector/DetCRD/scripts/CRD_o1_v02-SimRec.py b/Detector/DetCRD/scripts/CRD_o1_v02-SimRec.py index acee999de77be93b4b760ebbd2e2e23c3a91698d..253ea21a71125f20f9216094dd2071e2fdd950e4 100644 --- a/Detector/DetCRD/scripts/CRD_o1_v02-SimRec.py +++ b/Detector/DetCRD/scripts/CRD_o1_v02-SimRec.py @@ -84,6 +84,23 @@ detsimalg.AnaElems = [ ] detsimalg.RootDetElem = "WorldDetElemTool" +dedxoption = "BetheBlochEquationDedxSimTool" +from Configurables import DriftChamberSensDetTool +dc_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool") +dc_sensdettool.DedxSimTool = dedxoption + +from Configurables import DummyDedxSimTool +from Configurables import BetheBlochEquationDedxSimTool + +if dedxoption == "DummyDedxSimTool": + dedx_simtool = DummyDedxSimTool("DummyDedxSimTool") +elif dedxoption == "BetheBlochEquationDedxSimTool": + dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool") + dedx_simtool.material_Z = 2 + dedx_simtool.material_A = 4 + dedx_simtool.scale = 10 + dedx_simtool.resolution = 0.0001 + from Configurables import MarlinEvtSeeder evtseeder = MarlinEvtSeeder("EventSeeder") diff --git a/Detector/DetInterface/include/DetInterface/IGeomSvc.h b/Detector/DetInterface/include/DetInterface/IGeomSvc.h index d4f508b99779f44e6b30811f4296ac722d8cf9c8..51c26406a307d3e66724d207a730bbeca823c216 100644 --- a/Detector/DetInterface/include/DetInterface/IGeomSvc.h +++ b/Detector/DetInterface/include/DetInterface/IGeomSvc.h @@ -27,11 +27,6 @@ namespace dd4hep { class StructExtension; -namespace gear{ - class ZPlanarParametersImpl; - class GearParametersImpl; -} -class TMaterial; // class G4VUserDetectorConstruction; class GAUDI_API IGeomSvc : virtual public IService { @@ -49,16 +44,6 @@ public: // short cut to retrieve the Decoder according to the Readout name virtual Decoder* getDecoder(const std::string& readout_name) = 0; - // obsolete parameter format, will remove once StructExtension<> validated - virtual const gear::ZPlanarParametersImpl* getVXDParameters() = 0; - - virtual const dd4hep::rec::ZPlanarData* getVXDData() = 0; - virtual const dd4hep::rec::ConicalSupportData* getBeamPipeData() =0; - - virtual const std::map<std::string,double>& getDetParameters(std::string s) = 0; - virtual double getDetParameter(std::string set_name, std::string par_name) = 0; - virtual TMaterial* getMaterial(std::string s) = 0; - virtual ~IGeomSvc() {} }; diff --git a/Detector/GeomSvc/src/GeomSvc.cpp b/Detector/GeomSvc/src/GeomSvc.cpp index 54736e6c617c0e4c2591fd14817641751fe67f1e..f7ae4a2bd6c04f6f728e51a8c251e1cd9a31575e 100644 --- a/Detector/GeomSvc/src/GeomSvc.cpp +++ b/Detector/GeomSvc/src/GeomSvc.cpp @@ -22,7 +22,7 @@ DECLARE_COMPONENT(GeomSvc) GeomSvc::GeomSvc(const std::string& name, ISvcLocator* svc) -: base_class(name, svc), m_dd4hep_geo(nullptr), m_vxdData(nullptr), m_beamPipeData(nullptr){ +: base_class(name, svc), m_dd4hep_geo(nullptr){ } @@ -38,39 +38,12 @@ GeomSvc::initialize() { // if failed to load the compact, a runtime error will be thrown. m_dd4hep_geo->fromCompact(m_dd4hep_xmls.value()); - dd4hep::DetElement world = m_dd4hep_geo->world(); - //info() << world.type() << " " << world.path() << " " << world.placementPath() << endmsg; - const std::map<std::string, dd4hep::DetElement>& subs = world.children(); - for(std::map<std::string, dd4hep::DetElement>::const_iterator it=subs.begin();it!=subs.end();it++){ - dd4hep::DetElement sub = it->second; - info() << it->first << " " << sub.path() << " " << sub.placementPath() << endmsg; - if(it->first=="Tube"){ - dd4hep::Volume vol = sub.volume(); - dd4hep::Solid solid = vol.solid(); - //info() << " " << solid.type() << " " << solid.name() << endmsg; - const std::map<std::string, dd4hep::DetElement>& pipes = sub.children(); - for(std::map<std::string, dd4hep::DetElement>::const_iterator it=pipes.begin();it!=pipes.end();it++){ - dd4hep::DetElement pipe = it->second; - //info() << " " << it->first << " " << pipe.id() << " " << pipe.path() << " " << pipe.placementPath() << endmsg; - } - try{ - m_beamPipeData = sub.extension<dd4hep::rec::ConicalSupportData>(); - } - catch(std::runtime_error& e){ - info() << e.what() << " " << m_beamPipeData << endmsg; - } - } - if(it->first=="VXD"){ - sc = convertVXD(sub); - } - } return sc; } StatusCode GeomSvc::finalize() { StatusCode sc; - if(m_vxdParameters) delete m_vxdParameters; return sc; } @@ -119,484 +92,3 @@ GeomSvc::getDecoder(const std::string& readout_name) { return decoder; } - - -const std::map<std::string,double>& GeomSvc::getDetParameters(std::string name){ - if(m_detParameters.find(name)!=m_detParameters.end()) return m_detParameters[name]; - else{ - char message[200]; - sprintf(message,"GeomSvc has not the parameter set named %s", name.c_str()); - throw std::runtime_error(message); - } -} - -double GeomSvc::getDetParameter(std::string set_name, std::string par_name){ - std::map<std::string, std::map<std::string,double> >::iterator it=m_detParameters.find(set_name); - if(it!=m_detParameters.end()){ - if(it->second.find(par_name)!=it->second.end()) return it->second[par_name]; - } - char message[200]; - sprintf(message,"GeomSvc has not the parameter named %s in set %s", par_name.c_str(), set_name.c_str()); - throw std::runtime_error(message); -} - -StatusCode GeomSvc::convertVXD(dd4hep::DetElement& vxd){ - StatusCode sc; - //fucd: another method to obtain parameters, but not fully for KalDet - bool extensionDataValid = true; - try{ - m_vxdData = vxd.extension<dd4hep::rec::ZPlanarData>(); - } - catch(std::runtime_error& e){ - extensionDataValid = false; - info() << e.what() << " " << m_vxdData << endmsg; - } - - std::vector<helpLayer> helpSensitives; - std::vector<helpLayer> helpLadders; - std::vector<int> helpNumberLadders; - std::vector<double> helpPhi0; - int helpCount=0; - int type=0; - double shellInnerRadius, shellOuterRadius, shellHalfLength, gap, shellRadLength; - int nLadders=0; - double phi0=0; - helpLayer thisLadder; - double beryllium_ladder_block_length=0,end_electronics_half_z=0,side_band_electronics_width=0; - double rAlu, drAlu, rSty, drSty, dzSty, rInner, aluEndcapZ, aluHalfZ, alu_RadLen, Cryostat_dEdx; - double VXDSupportDensity, VXDSupportZeff, VXDSupportAeff, VXDSupportRadLen; - dd4hep::Volume vxd_vol = vxd.volume(); - for(int i=0;i<vxd_vol->GetNdaughters();i++){ - TGeoNode* daughter = vxd_vol->GetNode(i); - std::string nodeName = daughter->GetName(); - //info() << daughter->GetName() << endmsg; - if(nodeName=="VXD_support_assembly_0"){ - TGeoNode* shell = FindNode(daughter, "SupportShell"); - if(shell){ - const TGeoShape* shape_shell = shell->GetVolume()->GetShape(); - //fucd: IsA() method does not always work for TGeoTube, sometimes, strange? - //if(shape_shell->IsA()==TGeoTube::Class()){ - if(shape_shell->TestShapeBit(TGeoTube::kGeoTube)){ - const TGeoTube* tube = (const TGeoTube*) shape_shell; - shellInnerRadius = tube->GetRmin()*CLHEP::cm; - shellOuterRadius = tube->GetRmax()*CLHEP::cm; - shellHalfLength = tube->GetDz()*CLHEP::cm; - } - else{ - error() << shell->GetName() << " is not a TGeoTube! Shape bits = " << shape_shell->TestShapeBits(0xFFFFFFFF) << endmsg; - } - TGeoMaterial* mat = shell->GetMedium()->GetMaterial(); - shellRadLength = mat->GetRadLen()*CLHEP::cm; - } - TGeoNode* block = FindNode(daughter, "BerylliumAnnulusBlock"); - if(block){ - const TGeoShape* shape_block = block->GetVolume()->GetShape(); - if(shape_block->IsA()==TGeoBBox::Class()){ - const TGeoBBox* box = (const TGeoBBox*) shape_block; - beryllium_ladder_block_length = box->GetDY()*CLHEP::cm; - } - else{ - error() << block->GetName() << " is not a TGeoTube! Shape bits = " << shape_block->TestShapeBits(0xFFFFFFFF) << endmsg; - } - } - TGeoNode* skin = FindNode(daughter, "CryostatAluSkinBarrel"); - if(skin){ - const TGeoShape* shape_skin = skin->GetVolume()->GetShape(); - if(shape_skin->TestShapeBit(TGeoTube::kGeoTube)){ - const TGeoTube* tube = (const TGeoTube*) shape_skin; - rAlu = tube->GetRmin()*CLHEP::cm; - drAlu = tube->GetRmax()*CLHEP::cm - rAlu; - aluHalfZ = tube->GetDz()*CLHEP::cm; - //info() << rmin << "," << rmax << "," << zhalf << endmsg; - } - else{ - error() << skin->GetName() << " is not a TGeoTube! Shape bits = " << shape_skin->TestShapeBits(0xFFFFFFFF) << endmsg; - } - } - TGeoNode* foam = FindNode(daughter, "CryostatFoamBarrel"); - if(foam){ - const TGeoShape* shape_foam = foam->GetVolume()->GetShape(); - if(shape_foam->TestShapeBit(TGeoTube::kGeoTube)){ - const TGeoTube* tube = (const TGeoTube*) shape_foam; - rSty = tube->GetRmin()*CLHEP::cm; - drSty = tube->GetRmax()*CLHEP::cm - rSty; - dzSty = tube->GetDz()*CLHEP::cm; - //info() << rmin << "," << rmax << "," << zhalf << endmsg; - } - else{ - error() << foam->GetName() << " is not a TGeoTube! Shape bits = " << shape_foam->TestShapeBits(0xFFFFFFFF) << endmsg; - } - } - TGeoNode* skinEnd = FindNode(daughter, "CryostatAluSkinEndPlateInner"); - if(skinEnd){ - const TGeoShape* shape_skinEnd = skinEnd->GetVolume()->GetShape(); - if(shape_skinEnd->TestShapeBit(TGeoTube::kGeoTube)){ - const TGeoTube* tube = (const TGeoTube*) shape_skinEnd; - rInner = tube->GetRmin()*CLHEP::cm; - double rmax = tube->GetRmax()*CLHEP::cm; - drAlu = tube->GetDz()*CLHEP::cm*2; - //info() << rmin << "," << rmax << "," << zhalf << endmsg; - } - else{ - error() << skinEnd->GetName() << " is not a TGeoTube! Shape bits = " << shape_skinEnd->TestShapeBits(0xFFFFFFFF) << endmsg; - } - } - TGeoNode* shellEnd = FindNode(daughter, "EndPlateShell_outer"); - if(shellEnd){ - const TGeoShape* shape_shellEnd = shellEnd->GetVolume()->GetShape(); - if(shape_shellEnd->TestShapeBit(TGeoTube::kGeoTube)){ - const TGeoTube* tube = (const TGeoTube*) shape_shellEnd; - double rmin = tube->GetRmin()*CLHEP::cm; - double rmax = tube->GetRmax()*CLHEP::cm; - double zhalf = tube->GetDz()*CLHEP::cm; - //info() << rmin << "," << rmax << "," << zhalf << endmsg; - } - else{ - error() << shellEnd->GetName() << " is not a TGeoTube! Shape bits = " << shape_shellEnd->TestShapeBits(0xFFFFFFFF) << endmsg; - } - } - - } - else if(nodeName=="layer_assembly_0_1"){ - if(TGeoNode* side_band = FindNode(daughter, "ElectronicsBand")){ - const TGeoShape* shape_band = side_band->GetVolume()->GetShape(); - if(shape_band->IsA()==TGeoBBox::Class()){ - const TGeoBBox* box = (const TGeoBBox*) shape_band; - side_band_electronics_width = box->GetDX()*CLHEP::cm*2; - //info() << "fucd: "<< box->GetDX() << " " << box->GetDY() << " " << box->GetDZ() <<endmsg; - } - else{ - error() << "ElectronicsBand is not a TGeoBBox!!!"<< endmsg; - } - } - if(TGeoNode* end = FindNode(daughter, "ElectronicsEnd")){ - const TGeoShape* shape_end = end->GetVolume()->GetShape(); - if(shape_end->IsA()==TGeoBBox::Class()){ - const TGeoBBox* box = (const TGeoBBox*) shape_end; - end_electronics_half_z = box->GetDY()*CLHEP::cm; - //info() << "fucd: " << box->GetDX() << " " << box->GetDY() << " " << box->GetDZ() << endmsg; - } - else{ - error() << "ElectronicsEnd is not a TGeoBBox!!!"<< endmsg; - } - } - } - - /* - for(int j=0;j<daughter->GetNdaughters();j++){ - TGeoNode* next = daughter->GetDaughter(j); - info() << "fucd: " << next->GetName() << endmsg; - } - */ - } - - const std::map<std::string, dd4hep::DetElement>& components = vxd.children(); - for(std::map<std::string, dd4hep::DetElement>::const_iterator it=components.begin();it!=components.end();it++){ - dd4hep::DetElement component = it->second; - dd4hep::Volume vol = component.volume(); - dd4hep::PlacedVolume phys = component.placement(); - TGeoMaterial* mat = vol->GetMaterial(); - const TGeoShape* shape = vol->GetShape(); - const dd4hep::PlacedVolumeExtension::VolIDs& ids = phys.volIDs(); - //info() << " " << it->first << " " << vol->GetName() << " " << component.id() << " " << component.path() << " " << component.placementPath() << endmsg; - //info() << " " << shape->GetName() << " " << vol.solid().name() << endmsg; - //info() << " " << mat->GetName() << " " << mat->GetRadLen() << endmsg; - //info() << " " << ids.str() << endmsg; - //info() << " " << vol->GetNdaughters() << endmsg; - //double radL = mat->GetRadLen(); - //dd4hep::Solid solid = vol.solid(); - //info() << " " << sh->TestShapeBit(TGeoShape::kGeoBox) << " " << sh->GetName() << " " << phys.material().radLength() << endmsg; - if(vol.isSensitive()&&shape->IsA()==TGeoBBox::Class()){ - int iLayer = ids.find("layer")->second; - int iModule = ids.find("module")->second; - int iSide = ids.find("side")->second; - //info() << " layer=" << iLayer << " module=" << iModule << mat->GetName() << endmsg; - if(iModule==0&&iLayer==helpCount+1){ - helpCount++; - helpSensitives.push_back(thisLadder); - helpLadders.push_back(thisLadder); - helpNumberLadders.push_back(nLadders); - helpPhi0.push_back(phi0); - nLadders = 0; - thisLadder.length = 0; - } - if(iLayer == helpCount){ - if(iModule == 0){ - const TGeoBBox* box = (const TGeoBBox*) shape; - double width = box->GetDX()*CLHEP::cm; - double length = box->GetDY()*CLHEP::cm; - double thickness = box->GetDZ()*CLHEP::cm; - TGeoMatrix* matrix = phys->GetMatrix(); - const double* pos = matrix->GetTranslation(); - const double* rot_data = matrix->GetRotationMatrix(); - TGeoRotation rot; - rot.SetMatrix(rot_data); - double theta,phi,psi; - rot.GetAngles(phi,theta,psi); - phi *= TMath::DegToRad(); - theta *= TMath::DegToRad(); - psi *= TMath::DegToRad(); - phi0 = -TMath::PiOver2()+phi; - double distance = fabs(cos(phi0)*sin(theta)*pos[0]+sin(phi0)*sin(theta)*pos[1]+cos(theta)*pos[2]); - double offset = sqrt(pos[0]*pos[0]+pos[1]*pos[1]-distance*distance)*pos[0]/fabs(pos[0])*CLHEP::cm; - distance *= CLHEP::cm; - distance -= thickness; - double radL = mat->GetRadLen()*CLHEP::cm; - //info() << " -> " << helpCount << ": " << distance << " " << cos(atan2(pos[1],pos[0])-phi)*sqrt(pos[0]*pos[0]+pos[1]*pos[1]) << endmsg; - thisLadder.distance = distance; - thisLadder.offset = offset; - thisLadder.thickness = thickness; - thisLadder.length += length; - thisLadder.width = width; - thisLadder.radLength = radL; - thisLadder.z = pos[2]*CLHEP::cm; - } - if(iModule==nLadders) nLadders++; - } - } - //info() << " " << vol.solid().type() << " " << vol.solid().name() << " " << vol->GetNdaughters() << endmsg; - else if(it->first=="VXD_support"){ - helpCount++; - helpSensitives.push_back(thisLadder); - helpLadders.push_back(thisLadder); - helpNumberLadders.push_back(nLadders); - helpPhi0.push_back(phi0); - nLadders = 0; - if(vol->GetNdaughters()==0) error() << "!!!!!!!!!" << endmsg; - - int nFlexCable = 0, nFoamSpacer=0, nMetalTraces=0; - int currentLayer = -1; - double tFlexCable, tFoamSpacer, tMetalTraces; - double radLFlexCable, radLFoamSpacer, radLMetalTraces; - double intLFlexCable, intLFoamSpacer, intLMetalTraces; - double dFlexCable, dFoamSpacer, dMetalTraces; - double metalZeff, metalZAeff, foamZeff, foamZAeff, flexZeff, flexZAeff; - for(int i=0;i<vol->GetNdaughters();i++){ - TGeoNode* daughter = vol->GetNode(i); - TGeoMaterial* matDaughter = daughter->GetMedium()->GetMaterial(); - const TGeoShape* shape_sup = daughter->GetVolume()->GetShape(); - TGeoMatrix* matrix = daughter->GetMatrix(); - const double* pos = matrix->GetTranslation(); - const double* rot_data = matrix->GetRotationMatrix(); - TGeoRotation rot; - rot.SetMatrix(rot_data); - double theta,phi,psi; - rot.GetAngles(phi,theta,psi); - phi *= TMath::DegToRad(); - theta *= TMath::DegToRad(); - psi *= TMath::DegToRad(); - phi0 = -TMath::PiOver2()+phi; - std::string phy_name = daughter->GetName(); - if(phy_name.find("FoamSpacer")==-1&&phy_name.find("FlexCable")==-1&&phy_name.find("MetalTraces")==-1){ - //info() << phy_name <<endmsg; - continue; - } - int iLayer = atoi(phy_name.substr(phy_name.find("_")+1,2).c_str()); - if(iLayer!=currentLayer){ - //info() << tFoamSpacer << "," << tFlexCable << "," << tMetalTraces << endmsg; - helpLadders[currentLayer].thickness = tFoamSpacer+tFlexCable+tMetalTraces; - helpLadders[currentLayer].radLength = helpLadders[currentLayer].thickness / (tFoamSpacer/radLFoamSpacer+tFlexCable/radLFlexCable+tMetalTraces/radLMetalTraces); - nFlexCable = 0; - nFoamSpacer=0; - nMetalTraces=0; - currentLayer=iLayer; - } - //info() << "ss pos=" << pos[0] << "," << pos[1] << "," << pos[2] << " distance=" << sqrt(pos[0]*pos[0]+pos[1]*pos[1]) << endmsg; - //info() << "ss rot=" << phi << "," << theta << "," << psi << endmsg; - //info() << "ss " << daughter->GetName() << " " << daughter->GetVolume()->GetName() << " " << endmsg; - if(shape_sup->IsA()==TGeoBBox::Class()&&(nFoamSpacer==0||nFlexCable==0||nMetalTraces==0)){ - const TGeoBBox* box = (const TGeoBBox*) shape_sup; - //info() << phy_name.substr(phy_name.find("_")+1,2) << " " << iLayer << " " << box->GetDX() << "," << box->GetDY() << "," << box->GetDZ() << endmsg; - //info() << "fucd: pos " << pos[0] << " " << pos[1] << " " << pos[2] << endmsg; - double distance = fabs(cos(phi0)*sin(theta)*pos[0]+sin(phi0)*sin(theta)*pos[1]+cos(theta)*pos[2]); - double offset = sqrt(pos[0]*pos[0]+pos[1]*pos[1]-distance*distance)*pos[0]/fabs(pos[0])*CLHEP::cm; - distance -= box->GetDZ(); - distance *= CLHEP::cm; - if(helpLadders[iLayer].distance == helpSensitives[iLayer].distance) helpLadders[iLayer].distance = distance; - else helpLadders[iLayer].distance = TMath::Min(helpLadders[iLayer].distance, distance); - //info() << phy_name << " " << distance << " " << offset << endmsg; - if(phy_name.find("FoamSpacer")!=-1&&nFoamSpacer==0){ - helpLadders[iLayer].offset = offset; - tFoamSpacer = box->GetDZ()*CLHEP::cm; - radLFoamSpacer = matDaughter->GetRadLen()*CLHEP::cm; - intLFoamSpacer = matDaughter->GetIntLen()*CLHEP::cm; - dFoamSpacer = matDaughter->GetDensity()*CLHEP::g/CLHEP::cm3; - //fucd: A calculated by TGeoMaterial class is not equal to Zeff/ZAeff, Zeff = sum(Zi*Ai/sumA), ZAeff = sum(Zi/Ai*A/totalA) - // use Zeff and ZAeff to keep same with Mokka case - //foamZ = matDaughter->GetZ(); - //foamA = matDaughter->GetA(); - double totalA = 0, Zeff = 0, ZAeff = 0; - for(int iEle = 0; iEle<matDaughter->GetNelements(); iEle++){ - totalA += matDaughter->GetElement(iEle)->A(); - } - for(int iEle = 0; iEle<matDaughter->GetNelements(); iEle++){ - double A, Z, w; - // by fucd: w!=A/totalA, strange! to fix - matDaughter->GetElementProp(A,Z,w,iEle); - Zeff += Z*w; - ZAeff += Z/A*w; - //info() << std::setprecision(16) << Z << " " << A << " " << A/totalA << " " << w << endmsg; - } - foamZeff = Zeff; - foamZAeff = ZAeff; - nFoamSpacer++; - } - if(phy_name.find("FlexCable")!=-1&&nFlexCable==0){ - helpLadders[iLayer].width = box->GetDX()*CLHEP::cm; - helpLadders[iLayer].length = box->GetDY()*CLHEP::cm-beryllium_ladder_block_length*2-end_electronics_half_z*2; - tFlexCable = box->GetDZ()*CLHEP::cm; - radLFlexCable = matDaughter->GetRadLen()*CLHEP::cm; - intLFlexCable = matDaughter->GetIntLen()*CLHEP::cm; - dFlexCable = matDaughter->GetDensity()*CLHEP::g/CLHEP::cm3; - double Zeff = 0, ZAeff = 0; - for(int iEle = 0; iEle<matDaughter->GetNelements(); iEle++){ - double A, Z, w; - matDaughter->GetElementProp(A,Z,w,iEle); - Zeff += Z*w; - ZAeff += Z/A*w; - //std::cout << std::setprecision(16) << Z << " " << A << " " << w << std::endl; - } - flexZeff = Zeff; - flexZAeff = ZAeff; - nFlexCable++; - } - if(phy_name.find("MetalTraces")!=-1&&nMetalTraces==0){ - tMetalTraces = box->GetDZ()*CLHEP::cm; - radLMetalTraces = matDaughter->GetRadLen()*CLHEP::cm; - intLMetalTraces = matDaughter->GetIntLen()*CLHEP::cm; - dMetalTraces = matDaughter->GetDensity()*CLHEP::g/CLHEP::cm3; - double totalA = 0, Zeff = 0, ZAeff = 0; - for(int iEle = 0; iEle<matDaughter->GetNelements(); iEle++){ - totalA += matDaughter->GetElement(iEle)->A(); - } - for(int iEle = 0; iEle<matDaughter->GetNelements(); iEle++){ - double A, Z, w; - matDaughter->GetElementProp(A,Z,w,iEle); - Zeff += Z*w; - ZAeff += Z/A*w; - //info() << Z << " " << A << " " << w << endmsg; - } - metalZeff = Zeff; - metalZAeff = ZAeff; - nMetalTraces++; - } - } - } - { - //info() << tFoamSpacer << "," << tFlexCable << "," << tMetalTraces << endmsg; - double tSupport = tMetalTraces + tFoamSpacer + tFlexCable; - helpLadders[currentLayer].thickness = tSupport; - helpLadders[currentLayer].radLength = helpLadders[currentLayer].thickness / (tFoamSpacer/radLFoamSpacer+tFlexCable/radLFlexCable+tMetalTraces/radLMetalTraces); - nFlexCable = 0; - nFoamSpacer=0; - nMetalTraces=0; - - //calculations of thickness fractions of each layer of the support - double metalTF = tMetalTraces / tSupport; - double foamTF = tFoamSpacer / tSupport; - double flexTF = tFlexCable / tSupport; - //info() << foamTF << "," << flexTF << "," << metalTF << endmsg; - //info() << dFoamSpacer/(CLHEP::kg/CLHEP::cm3) << "," << dFlexCable/(CLHEP::kg/CLHEP::cm3) << "," << dMetalTraces/(CLHEP::kg/CLHEP::cm3) << endmsg; - //info() << foamZeff << " " << flexZeff << " " << metalZeff << endmsg; - //info() << foamZAeff << " " << flexZAeff << " " << metalZAeff << endmsg; - G4double elemVol = 1*CLHEP::cm3; - G4double VXDSupportMass = (foamTF*dFoamSpacer + flexTF*dFlexCable + metalTF*dMetalTraces)*elemVol; - VXDSupportDensity = VXDSupportMass/elemVol; - - G4double foamFM = 100. * ((foamTF*(elemVol)*dFoamSpacer) / VXDSupportMass) ; - G4double kaptonFM = 100. * ((flexTF*(elemVol)*dFlexCable) / VXDSupportMass) ; - G4double metalFM = 100. * ((metalTF*(elemVol)*dMetalTraces) / VXDSupportMass) ; - - VXDSupportRadLen = helpLadders[currentLayer].radLength; - - VXDSupportZeff = (metalFM/100.)*metalZeff + (kaptonFM/100.)*flexZeff + (foamFM/100.)*foamZeff; - G4double VXDSupportZAeff = (metalFM/100.)*metalZAeff + (kaptonFM/100.)*flexZAeff + (foamFM/100.)*foamZAeff; - VXDSupportAeff = VXDSupportZeff / VXDSupportZAeff; - G4double VXDSupportIntLength = 1. / ((metalTF/intLMetalTraces) + (flexTF/intLFlexCable) + (foamTF/intLFoamSpacer)); - VXDSupportDensity = 1000*VXDSupportDensity/(CLHEP::g/CLHEP::cm3); - //info() << "fucd: " << VXDSupportZeff << " " << VXDSupportAeff << " " << VXDSupportRadLen << " " << VXDSupportIntLength << " " << VXDSupportDensity << endmsg; - //info() << intLMetalTraces << " " << intLFlexCable << " " << intLFoamSpacer <<endmsg; - } - } - //info() << it->first << endmsg; - } - if(end_electronics_half_z>0 && side_band_electronics_width==0) type = gear::ZPlanarParametersImpl::CCD ; - if(side_band_electronics_width>0 && end_electronics_half_z==0 ) type = gear::ZPlanarParametersImpl::CMOS ; - if(side_band_electronics_width>0 && end_electronics_half_z>0) type = gear::ZPlanarParametersImpl::HYBRID ; - - m_vxdParameters = new gear::ZPlanarParametersImpl(type, shellInnerRadius, shellOuterRadius, shellHalfLength, gap, shellRadLength ); - // by fucd: debug info, if validated enough, merge them in future - info() << "=====================from convertor==============================" << endmsg; - info() << type << " " << shellInnerRadius << " " << shellOuterRadius << " " << shellHalfLength << " " << gap << " " << shellRadLength << endmsg; - for(int i=0;i<helpCount;i++){ - m_vxdParameters->addLayer(helpNumberLadders[i] , helpPhi0[i] , - helpLadders[i].distance , helpLadders[i].offset, helpLadders[i].thickness*2 , - helpLadders[i].length , helpLadders[i].width*2 , helpLadders[i].radLength , - helpSensitives[i].distance, helpSensitives[i].offset , helpSensitives[i].thickness*2 , - helpSensitives[i].length , helpSensitives[i].width*2 , helpSensitives[i].radLength ) ; - info() << "fucd " << i << ": " << helpNumberLadders[i] << ", " << helpPhi0[i] << ", " - << helpLadders[i].distance << ", " << helpLadders[i].offset << ", " << helpLadders[i].thickness*2 << ", " << helpLadders[i].length << ", " - << helpLadders[i].width*2 << ", " << helpLadders[i].radLength << ", " << helpSensitives[i].distance << ", " << helpSensitives[i].offset << ", " - << helpSensitives[i].thickness*2 << ", " << helpSensitives[i].length << ", " << helpSensitives[i].width*2 << ", " << helpSensitives[i].radLength << endmsg; - } - //m_vxdInfra = new gear::GearParametersImpl; - //CryostatAlRadius, CryostatAlThickness, CryostatAlInnerR, CryostatAlZEndCap, CryostatAlHalfZ - //m_vxdInfra->setDoubleVal("CryostatAlRadius",rAlu); - //m_vxdInfra->setDoubleVal("CryostatAlThickness",drAlu); - //m_vxdInfra->setDoubleVal("CryostatAlInnerR",rInner); - //m_vxdInfra->setDoubleVal("CryostatAlZEndCap",aluEndcapZ=dzSty + drSty + drAlu / 2); - //m_vxdInfra->setDoubleVal("CryostatAlHalfZ",aluHalfZ= dzSty + drSty); - // change GearParametersImpl to map - std::map<std::string,double> vxdInfra; - vxdInfra["CryostatAlRadius"] = rAlu; - vxdInfra["CryostatAlThickness"] = drAlu; - vxdInfra["CryostatAlInnerR"] = rInner; - vxdInfra["CryostatAlZEndCap"] = dzSty+drSty+drAlu/2; - vxdInfra["CryostatAlHalfZ"] = dzSty+drSty; - m_detParameters["VXDInfra"] = vxdInfra; - //effective A different with what in Mokka, fix them as Mokka's - //m_materials["VXDSupportMaterial"] = new TMaterial("VXDSupportMaterial", "", VXDSupportAeff, VXDSupportZeff, VXDSupportDensity, VXDSupportRadLen, 0.); - m_materials["VXDSupportMaterial"] = new TMaterial("VXDSupportMaterial", "", 2.075865162e+01, 1.039383117e+01, 2.765900000e+02/1000, 1.014262421e+02, 0.); - - info() << "=====================from ZPlanarData==============================" << endmsg; - if(m_vxdData){ - info() << m_vxdData->rInnerShell << " " << m_vxdData->rOuterShell << " " << m_vxdData->zHalfShell << " " << m_vxdData->gapShell << endmsg; - const std::vector<dd4hep::rec::ZPlanarData::LayerLayout>& layers = m_vxdData->layers; - for(int i=0;i<layers.size();i++){ - const dd4hep::rec::ZPlanarData::LayerLayout& thisLayer = layers[i]; - info() << i << ": " << thisLayer.ladderNumber << "," << thisLayer.phi0 << "," << thisLayer.distanceSupport << "," << thisLayer.offsetSupport << "," - << thisLayer.thicknessSupport << "," << thisLayer.zHalfSupport << "," << thisLayer.widthSupport << "," << "NULL," - << thisLayer.distanceSensitive << "," << thisLayer.offsetSensitive << "," << thisLayer.thicknessSensitive << "," << thisLayer.zHalfSensitive << "," - << thisLayer.widthSensitive << ",NULL" << endmsg; - } - } - info() << rAlu << " " << drAlu << " " << rInner << " " << aluEndcapZ << " " << aluHalfZ << endmsg; - //info() << m_materials["VXDSupportMaterial"] << endmsg; - return sc; -} - -TGeoNode* GeomSvc::FindNode(TGeoNode* mother, char* name){ - TGeoNode* next = 0; - if(mother->GetNdaughters()!=0){ - for(int i=0;i<mother->GetNdaughters();i++){ - TGeoNode* daughter = mother->GetDaughter(i); - std::string s = daughter->GetName(); - //info() << "current: " << s << " search for" << name << endmsg; - if(s.find(name)!=-1){ - next = daughter; - break; - } - else{ - next = FindNode(daughter, name); - } - } - } - return next; -} - -TMaterial* GeomSvc::getMaterial(std::string name){ - std::map<std::string, TMaterial*>::const_iterator it = m_materials.find(name); - if(it!=m_materials.end()) return it->second; - else return 0; - -} diff --git a/Detector/GeomSvc/src/GeomSvc.h b/Detector/GeomSvc/src/GeomSvc.h index 4ef39d2f0644c25b666145d4ee4a5caffd8420e1..119e2ea5870db041ad48bf4bf0175af290af51cd 100644 --- a/Detector/GeomSvc/src/GeomSvc.h +++ b/Detector/GeomSvc/src/GeomSvc.h @@ -34,45 +34,15 @@ class GeomSvc: public extends<Service, IGeomSvc> { dd4hep::DetElement getDD4HepGeo() override; dd4hep::Detector* lcdd() override; - const gear::ZPlanarParametersImpl* getVXDParameters() override {return m_vxdParameters;}; - const dd4hep::rec::ZPlanarData* getVXDData() override {return m_vxdData;}; - const dd4hep::rec::ConicalSupportData* getBeamPipeData() override {return m_beamPipeData;}; - - const std::map<std::string,double>& getDetParameters(std::string name) override; - double getDetParameter(std::string set_name, std::string par_name) override; - TMaterial* getMaterial(std::string name); - private: - StatusCode convertVXD(dd4hep::DetElement& sub); - - Decoder* getDecoder(const std::string& readout_name) override; - + Decoder* getDecoder(const std::string& readout_name) override; + private: - TGeoNode* FindNode(TGeoNode* mother, char* name); // DD4hep XML compact file path Gaudi::Property<std::string> m_dd4hep_xmls{this, "compact"}; // dd4hep::Detector* m_dd4hep_geo; - - - gear::ZPlanarParametersImpl* m_vxdParameters{nullptr}; - dd4hep::rec::ZPlanarData* m_vxdData{nullptr}; - dd4hep::rec::ConicalSupportData* m_beamPipeData{nullptr}; - - //gear::GearParametersImpl* m_vxdInfra; - std::map<std::string, std::map<std::string,double> > m_detParameters; - std::map<std::string, TMaterial*> m_materials; - struct helpLayer { - double distance =0; - double offset =0; - double thickness =0; - double length =0; - double width =0; - double radLength =0; - double z =0; - double foam_spacer_radLength =0; - }; }; #endif // GeomSvc_h diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h index 87debdd87da87e2e46ae6305103e421e00ac03f2..d645f2db44812b4cbdd2281f66b7ce7657be6824 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h +++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h @@ -25,7 +25,8 @@ #include <string> -typedef std::vector<edm4hep::CalorimeterHit *> CalorimeterHitVector; +//typedef std::vector<edm4hep::CalorimeterHit *> CalorimeterHitVector; +typedef std::vector<const edm4hep::CalorimeterHit *> CalorimeterHitVector; namespace gear { class GearMgr; } @@ -174,25 +175,25 @@ private: * @brief Get common calo hit properties: position, parent address, input energy and time * */ - void GetCommonCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const; + void GetCommonCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const; /** * @brief Get end cap specific calo hit properties: cell size, absorber radiation and interaction lengths, normal vector * */ - void GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, + void GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const; - void GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, + void GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const; /** * @brief Get barrel specific calo hit properties: cell size, absorber radiation and interaction lengths, normal vector * */ - void GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, + void GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const; - void GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, + void GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const; @@ -200,13 +201,13 @@ private: * @brief Get number of active layers from position of a calo hit to the edge of the detector * */ - int GetNLayersFromEdge(edm4hep::CalorimeterHit *const pCaloHit) const; + int GetNLayersFromEdge(const edm4hep::CalorimeterHit *const pCaloHit) const; /** * @brief Get the maximum radius of a calo hit in a polygonal detector structure * */ - float GetMaximumRadius(edm4hep::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const; + float GetMaximumRadius(const edm4hep::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const; /** * @brief Get the layer coding string from the provided cell id encoding string diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/MCParticleCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/MCParticleCreator.h index ba37ad54820b5970d0da2ee150d42b57d2987ea4..4e446cf9c59ed15ea3f28034f99adedd8f407917 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/include/MCParticleCreator.h +++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/MCParticleCreator.h @@ -78,7 +78,7 @@ private: const Settings m_settings; ///< The mc particle creator settings const pandora::Pandora *m_pPandora; ///< Address of the pandora object to create the mc particles const float m_bField; ///< The bfield - std::map<unsigned int, edm4hep::MCParticle*>* m_id_pMC_map; + std::map<unsigned int, const edm4hep::MCParticle*>* m_id_pMC_map; }; inline void MCParticleCreator::Reset() diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h index b8b8ec1844545b8ea0456a5f95b284e58e58eaf3..e6059bc7a36bd3d569ef6711d3d9333dc31be42b 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h +++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h @@ -22,7 +22,7 @@ namespace gear { class GearMgr; } class CollectionMaps; -typedef std::vector<edm4hep::Track *> TrackVector; +typedef std::vector<const edm4hep::Track *> TrackVector; typedef std::set<unsigned int> TrackList; typedef std::map<edm4hep::Track, int> TrackToPidMap; /* @@ -123,7 +123,7 @@ public: */ pandora::StatusCode CreateTrackAssociations(const CollectionMaps& collectionMaps); - edm4hep::Track* GetTrackAddress(const CollectionMaps& collectionMaps, const edm4hep::Track& pTrack ); + const edm4hep::Track* GetTrackAddress(const CollectionMaps& collectionMaps, const edm4hep::Track& pTrack ); /** * @brief Create tracks, insert user code here * @@ -196,7 +196,7 @@ private: * @brief Copy track states stored in tracks to pandora track parameters * */ - void GetTrackStates(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; + void GetTrackStates(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; /** * @brief Copy track state from track state instance to pandora input track state @@ -208,13 +208,13 @@ private: * @brief Obtain track time when it reaches ECAL * */ - float CalculateTrackTimeAtCalorimeter(edm4hep::Track *const pTrack) const; + float CalculateTrackTimeAtCalorimeter(const edm4hep::Track *const pTrack) const; /** * @brief Decide whether track reaches the ecal surface * */ - void TrackReachesECAL(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; + void TrackReachesECAL(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; /** * @brief Determine whether a track can be used to form a pfo under the following conditions: @@ -222,7 +222,7 @@ private: * 2) if the track proves to have no cluster associations * */ - void DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; + void DefineTrackPfoUsage(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; /** * @brief Whether track passes the quality cuts required in order to be used to form a pfo @@ -230,19 +230,19 @@ private: * * @return boolean */ - bool PassesQualityCuts(edm4hep::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const; + bool PassesQualityCuts(const edm4hep::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const; /** * @brief Get number of hits in TPC of a track * */ - int GetNTpcHits(edm4hep::Track *const pTrack) const; + int GetNTpcHits(const edm4hep::Track *const pTrack) const; /** * @brief Get number of hits in FTD of a track * */ - int GetNFtdHits(edm4hep::Track *const pTrack) const; + int GetNFtdHits(const edm4hep::Track *const pTrack) const; const Settings m_settings; ///< The track creator settings const pandora::Pandora *m_pPandora; ///< Address of the pandora object to create tracks and track relationships diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp index d13b5e5ad5c709e0daf3a3eec0fc6bd819d65ff4..29b9adcbfa023d2abbb5280e7a028e4aff224439 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp +++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp @@ -240,7 +240,7 @@ pandora::StatusCode CaloHitCreator::CreateECalCaloHits(const CollectionMaps& col try { if(m_settings.m_debug) std::cout<<"CaloHitCreator for "<<tmp_col_name<<std::endl; - auto pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; + auto & pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; const int nElements(pCaloHitCollection.size()); if (0 == nElements) @@ -276,8 +276,8 @@ pandora::StatusCode CaloHitCreator::CreateECalCaloHits(const CollectionMaps& col { try { - auto pCaloHit0 = pCaloHitCollection.at(i); - auto pCaloHit = &(pCaloHit0); + //auto pCaloHit = const_cast<edm4hep::CalorimeterHit*>(&(pCaloHitCollection.at(i))); + auto pCaloHit = &(pCaloHitCollection.at(i)); if (NULL == pCaloHit) throw ("CreateECalCaloHits pCaloHit Collection type mismatch"); @@ -395,7 +395,7 @@ pandora::StatusCode CaloHitCreator::CreateHCalCaloHits(const CollectionMaps& col if(collectionMaps.collectionMap_CaloHit.find(tmp_col_name) == collectionMaps.collectionMap_CaloHit.end()) { if(m_settings.m_debug) std::cout<<"not find "<<tmp_col_name<<std::endl; continue;} try { - auto pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; + auto & pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; const int nElements(pCaloHitCollection.size()); if (0 == nElements) @@ -431,8 +431,7 @@ pandora::StatusCode CaloHitCreator::CreateHCalCaloHits(const CollectionMaps& col { try { - auto pCaloHit0 = pCaloHitCollection.at(i); - auto pCaloHit = &(pCaloHit0); + auto pCaloHit = &(pCaloHitCollection.at(i)); if (NULL == pCaloHit) throw ("CreateHCalCaloHits Collection type mismatch"); @@ -520,7 +519,7 @@ pandora::StatusCode CaloHitCreator::CreateMuonCaloHits(const CollectionMaps& col if(collectionMaps.collectionMap_CaloHit.find(tmp_col_name) == collectionMaps.collectionMap_CaloHit.end()) {if(m_settings.m_debug) std::cout<<"not find "<<tmp_col_name<<std::endl; continue;} try { - auto pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; + auto & pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(tmp_col_name))->second; const int nElements(pCaloHitCollection.size()); if (0 == nElements) @@ -558,8 +557,7 @@ pandora::StatusCode CaloHitCreator::CreateMuonCaloHits(const CollectionMaps& col { try { - auto pCaloHit0 = pCaloHitCollection.at(i); - auto pCaloHit = &(pCaloHit0); + auto pCaloHit = &(pCaloHitCollection.at(i)); if (NULL == pCaloHit) throw ("Muon Collection type mismatch"); @@ -661,7 +659,7 @@ pandora::StatusCode CaloHitCreator::CreateLCalCaloHits(const CollectionMaps& col if(collectionMaps.collectionMap_CaloHit.find(*iter) == collectionMaps.collectionMap_CaloHit.end()) {if(m_settings.m_debug)std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(*iter))->second; + auto & pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(*iter))->second; const int nElements(pCaloHitCollection.size()); if (0 == nElements) @@ -679,8 +677,7 @@ pandora::StatusCode CaloHitCreator::CreateLCalCaloHits(const CollectionMaps& col { try { - auto pCaloHit0 = pCaloHitCollection.at(i); - auto pCaloHit = &(pCaloHit0); + auto pCaloHit = &(pCaloHitCollection.at(i)); if (NULL == pCaloHit) throw ("LCal Collection type mismatch"); @@ -736,7 +733,7 @@ pandora::StatusCode CaloHitCreator::CreateLHCalCaloHits(const CollectionMaps& co if(collectionMaps.collectionMap_CaloHit.find(*iter) == collectionMaps.collectionMap_CaloHit.end()) {if(m_settings.m_debug) std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(*iter))->second; + auto & pCaloHitCollection = (collectionMaps.collectionMap_CaloHit.find(*iter))->second; const int nElements(pCaloHitCollection.size()); if (0 == nElements) @@ -753,8 +750,7 @@ pandora::StatusCode CaloHitCreator::CreateLHCalCaloHits(const CollectionMaps& co { try { - auto pCaloHit0 = pCaloHitCollection.at(i); - auto pCaloHit = &(pCaloHit0); + auto pCaloHit = &(pCaloHitCollection.at(i)); if (NULL == pCaloHit) throw ("LHCal Collection type mismatch"); @@ -802,7 +798,7 @@ pandora::StatusCode CaloHitCreator::CreateLHCalCaloHits(const CollectionMaps& co //------------------------------------------------------------------------------------------------------------------------------------------ -void CaloHitCreator::GetCommonCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const +void CaloHitCreator::GetCommonCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const { const float pCaloHitPosition[3]={pCaloHit->getPosition()[0], pCaloHit->getPosition()[1], pCaloHit->getPosition()[2]}; const pandora::CartesianVector positionVector(pCaloHitPosition[0], pCaloHitPosition[1], pCaloHitPosition[2]); @@ -817,7 +813,7 @@ void CaloHitCreator::GetCommonCaloHitProperties(edm4hep::CalorimeterHit *const p //------------------------------------------------------------------------------------------------------------------------------------------ -void CaloHitCreator::GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, +void CaloHitCreator::GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const { caloHitParameters.m_hitRegion = pandora::ENDCAP; @@ -862,7 +858,7 @@ void CaloHitCreator::GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const p } //------------------------------------------------------------------------------------------------------------------------------------------ -void CaloHitCreator::GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, +void CaloHitCreator::GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const { caloHitParameters.m_hitRegion = pandora::ENDCAP; @@ -914,7 +910,7 @@ void CaloHitCreator::GetEndCapCaloHitProperties(edm4hep::CalorimeterHit *const p } //------------------------------------------------------------------------------------------------------------------------------------------ -void CaloHitCreator::GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, +void CaloHitCreator::GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout, unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const { @@ -977,7 +973,7 @@ void CaloHitCreator::GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const p } } -void CaloHitCreator::GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, +void CaloHitCreator::GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers, unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const { @@ -1054,7 +1050,7 @@ void CaloHitCreator::GetBarrelCaloHitProperties(edm4hep::CalorimeterHit *const p //------------------------------------------------------------------------------------------------------------------------------------------ -int CaloHitCreator::GetNLayersFromEdge(edm4hep::CalorimeterHit *const pCaloHit) const +int CaloHitCreator::GetNLayersFromEdge(const edm4hep::CalorimeterHit *const pCaloHit) const { // Calo hit coordinate calculations const float barrelMaximumRadius(this->GetMaximumRadius(pCaloHit, m_hCalBarrelOuterSymmetry, m_hCalBarrelOuterPhi0)); @@ -1096,7 +1092,7 @@ int CaloHitCreator::GetNLayersFromEdge(edm4hep::CalorimeterHit *const pCaloHit) //------------------------------------------------------------------------------------------------------------------------------------------ -float CaloHitCreator::GetMaximumRadius(edm4hep::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const +float CaloHitCreator::GetMaximumRadius(const edm4hep::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const { const float pCaloHitPosition[3]={pCaloHit->getPosition()[0], pCaloHit->getPosition()[1], pCaloHit->getPosition()[2]}; diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp index ef457a7b4a0691bd0df5666d59709efa87272844..1912eee92592f0b8071fcabed38259a61c049f87 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp +++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp @@ -22,7 +22,7 @@ MCParticleCreator::MCParticleCreator(const Settings &settings, const pandora::Pa m_pPandora(pPandora), m_bField(settings.m_bField) { -m_id_pMC_map = new std::map<unsigned int, edm4hep::MCParticle*>; +m_id_pMC_map = new std::map<unsigned int, const edm4hep::MCParticle*>; } //------------------------------------------------------------------------------------------------------------------------------------------ @@ -41,19 +41,20 @@ pandora::StatusCode MCParticleCreator::CreateMCParticles(const CollectionMaps& c if(collectionMaps.collectionMap_MC.find(*iter) == collectionMaps.collectionMap_MC.end()) continue; try { - auto pMCParticleCollection = (collectionMaps.collectionMap_MC.find(*iter))->second; + auto & pMCParticleCollection = (collectionMaps.collectionMap_MC.find(*iter))->second; std::cout<<"Do CreateMCParticles, collection:"<<(*iter)<<", size="<<pMCParticleCollection.size()<<std::endl; for (int im = 0; im < pMCParticleCollection.size(); im++) { try { - auto pMcParticle = pMCParticleCollection.at(im); + auto & pMcParticle = pMCParticleCollection.at(im); PandoraApi::MCParticle::Parameters mcParticleParameters; mcParticleParameters.m_energy = sqrt(pMcParticle.getMomentum()[0] * pMcParticle.getMomentum()[0] + pMcParticle.getMomentum()[1] * pMcParticle.getMomentum()[1] + pMcParticle.getMomentum()[2] * pMcParticle.getMomentum()[2] + pMcParticle.getMass() * pMcParticle.getMass()); mcParticleParameters.m_particleId = pMcParticle.getPDG(); mcParticleParameters.m_mcParticleType = pandora::MC_3D; mcParticleParameters.m_pParentAddress = &pMcParticle; unsigned int p_id = pMcParticle.id(); + //auto p_mc = const_cast<edm4hep::MCParticle*>(&pMcParticle); auto p_mc = &pMcParticle; (*m_id_pMC_map) [p_id] = p_mc; mcParticleParameters.m_momentum = pandora::CartesianVector(pMcParticle.getMomentum()[0], pMcParticle.getMomentum()[1], @@ -104,7 +105,7 @@ pandora::StatusCode MCParticleCreator::CreateMCParticles(const CollectionMaps& c pandora::StatusCode MCParticleCreator::CreateCaloHitToMCParticleRelationships(const CollectionMaps& collectionMaps, const CalorimeterHitVector &calorimeterHitVector) const { - typedef std::map<edm4hep::MCParticle *, float> MCParticleToEnergyWeightMap; + typedef std::map<const edm4hep::MCParticle *, float> MCParticleToEnergyWeightMap; MCParticleToEnergyWeightMap mcParticleToEnergyWeightMap; for (StringVector::const_iterator iter = m_settings.m_CaloHitRelationCollections.begin(), iterEnd = m_settings.m_CaloHitRelationCollections.end(); @@ -173,7 +174,8 @@ pandora::StatusCode MCParticleCreator::CreateTrackToMCParticleRelationships(cons const pandora::Helix helixFit(pTrack->getTrackStates(0).phi, pTrack->getTrackStates(0).D0, pTrack->getTrackStates(0).Z0, pTrack->getTrackStates(0).omega, pTrack->getTrackStates(0).tanLambda, m_bField); const float recoMomentum(helixFit.GetMomentum().GetMagnitude()); // Use momentum magnitude to identify best mc particle - edm4hep::MCParticle *pBestMCParticle = NULL; + //edm4hep::MCParticle *pBestMCParticle = NULL; + int best_mc_id = -1; float bestDeltaMomentum(std::numeric_limits<float>::max()); try { @@ -193,15 +195,18 @@ pandora::StatusCode MCParticleCreator::CreateTrackToMCParticleRelationships(cons const float deltaMomentum(std::fabs(recoMomentum - trueMomentum)); if (deltaMomentum < bestDeltaMomentum) { - pBestMCParticle =((*m_id_pMC_map)[ipa.id()]); + //pBestMCParticle =((*m_id_pMC_map)[ipa.id()]); + best_mc_id = ipa.id() ; bestDeltaMomentum = deltaMomentum; } } } } - if (NULL == pBestMCParticle) continue; - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackToMCParticleRelationship(*m_pPandora, pTrack, pBestMCParticle)); + //if (NULL == pBestMCParticle) continue; + if (best_mc_id == -1) continue; + //PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackToMCParticleRelationship(*m_pPandora, pTrack, pBestMCParticle)); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackToMCParticleRelationship(*m_pPandora, pTrack, (*m_id_pMC_map)[best_mc_id] ) ); } catch (pandora::StatusCodeException &statusCodeException) { diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp index ae33a07c79a7bd768fb6dcd1dc6e26e5de11d49a..940d116f14d5682f6adfdd530deba7777a0c9d0d 100644 --- a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp +++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp @@ -291,20 +291,20 @@ pandora::StatusCode TrackCreator::ExtractKinks(const CollectionMaps& collectionM if(collectionMaps.collectionMap_Vertex.find(*iter) == collectionMaps.collectionMap_Vertex.end()) { std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pKinkCollection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; + auto & pKinkCollection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; for (int i = 0, iMax = pKinkCollection.size(); i < iMax; ++i) { try { - auto pVertex0 = pKinkCollection.at(i); + auto & pVertex0 = pKinkCollection.at(i); auto pVertex = &(pVertex0); if (NULL == pVertex) throw ("Collection type mismatch"); //std::cout<<"pVertex getChi2="<<pVertex->getChi2()<<std::endl; //std::cout<<"pReconstructedParticle en="<<pReconstructedParticle.getEnergy()<<",type="<<pReconstructedParticle.getType()<<std::endl; - auto pReconstructedParticle = pVertex->getAssociatedParticle(); + auto & pReconstructedParticle = pVertex->getAssociatedParticle(); if (this->IsConflictingRelationship(pReconstructedParticle))continue; const int vertexPdgCode(pReconstructedParticle.getType()); @@ -395,17 +395,17 @@ pandora::StatusCode TrackCreator::ExtractProngsAndSplits(const CollectionMaps& c if(collectionMaps.collectionMap_Vertex.find(*iter) == collectionMaps.collectionMap_Vertex.end()) { std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pProngOrSplitCollection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; + auto & pProngOrSplitCollection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; for (int i = 0, iMax = pProngOrSplitCollection.size(); i < iMax; ++i) { try { - auto pVertex0 = pProngOrSplitCollection.at(i); + auto & pVertex0 = pProngOrSplitCollection.at(i); auto pVertex = &(pVertex0); if (NULL == pVertex) throw ("Collection type mismatch"); - const edm4hep::ReconstructedParticle pReconstructedParticle = pVertex->getAssociatedParticle(); + const edm4hep::ReconstructedParticle & pReconstructedParticle = pVertex->getAssociatedParticle(); if (this->IsConflictingRelationship(pReconstructedParticle))continue; @@ -461,18 +461,18 @@ pandora::StatusCode TrackCreator::ExtractV0s(const CollectionMaps& collectionMap if(collectionMaps.collectionMap_Vertex.find(*iter) == collectionMaps.collectionMap_Vertex.end()) { std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pV0Collection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; + auto & pV0Collection = (collectionMaps.collectionMap_Vertex.find(*iter))->second; for (int i = 0, iMax = pV0Collection.size(); i < iMax; ++i) { try { - auto pVertex0 = pV0Collection.at(i); + auto & pVertex0 = pV0Collection.at(i); auto pVertex = &(pVertex0); if (NULL == pVertex) throw ("Collection type mismatch"); - const edm4hep::ReconstructedParticle pReconstructedParticle = pVertex->getAssociatedParticle(); + const edm4hep::ReconstructedParticle & pReconstructedParticle = pVertex->getAssociatedParticle(); if (this->IsConflictingRelationship(pReconstructedParticle))continue; @@ -547,15 +547,15 @@ bool TrackCreator::IsConflictingRelationship(const edm4hep::ReconstructedParticl return false; } -edm4hep::Track* TrackCreator::GetTrackAddress(const CollectionMaps& collectionMaps, const edm4hep::Track& pTrack ) +const edm4hep::Track* TrackCreator::GetTrackAddress(const CollectionMaps& collectionMaps, const edm4hep::Track& pTrack ) { for (StringVector::const_iterator iter = m_settings.m_trackCollections.begin(), iterEnd = m_settings.m_trackCollections.end(); iter != iterEnd; ++iter) { if(collectionMaps.collectionMap_Track.find(*iter) == collectionMaps.collectionMap_Track.end()) { std::cout<<"not find "<<(*iter)<<std::endl; continue;} - auto pTrackCollection = (collectionMaps.collectionMap_Track.find(*iter))->second; + auto & pTrackCollection = (collectionMaps.collectionMap_Track.find(*iter))->second; for (int i = 0, iMax = pTrackCollection.size(); i < iMax; ++i) { - auto pTrack0 = pTrackCollection.at(i); + auto & pTrack0 = pTrackCollection.at(i); if (pTrack.id() == pTrack0.id()) return (&pTrack0); } } @@ -572,15 +572,14 @@ pandora::StatusCode TrackCreator::CreateTracks(const CollectionMaps& collectionM if(collectionMaps.collectionMap_Track.find(*iter) == collectionMaps.collectionMap_Track.end()) { std::cout<<"not find "<<(*iter)<<std::endl; continue;} try { - auto pTrackCollection = (collectionMaps.collectionMap_Track.find(*iter))->second; + auto & pTrackCollection = (collectionMaps.collectionMap_Track.find(*iter))->second; if(m_settings.m_debug) std::cout<<"TrackSize:"<<pTrackCollection.size()<<std::endl; for (int i = 0, iMax = pTrackCollection.size(); i < iMax; ++i) { try { - auto pTrack0 = pTrackCollection.at(i); - auto pTrack = (&pTrack0); + auto pTrack = &(pTrackCollection.at(i)); if (NULL == pTrack) throw ("Collection type mismatch"); if(m_settings.m_debug){ @@ -665,7 +664,7 @@ pandora::StatusCode TrackCreator::CreateTracks(const CollectionMaps& collectionM //------------------------------------------------------------------------------------------------------------------------------------------ -void TrackCreator::GetTrackStates(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const +void TrackCreator::GetTrackStates(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const { // for DD4HEP, 0 is IP, 1 is AtFirstHit, 2 is AtLastHit, 3 is AtCalo edm4hep::TrackState pTrackState = pTrack->getTrackStates(0); @@ -691,7 +690,7 @@ void TrackCreator::GetTrackStates(edm4hep::Track *const pTrack, PandoraApi::Trac //------------------------------------------------------------------------------------------------------------------------------------------ -float TrackCreator::CalculateTrackTimeAtCalorimeter(edm4hep::Track *const pTrack) const +float TrackCreator::CalculateTrackTimeAtCalorimeter(const edm4hep::Track *const pTrack) const { const pandora::Helix helix(pTrack->getTrackStates(0).phi, pTrack->getTrackStates(0).D0, pTrack->getTrackStates(0).Z0, pTrack->getTrackStates(0).omega, pTrack->getTrackStates(0).tanLambda, m_bField); const pandora::CartesianVector &referencePoint(helix.GetReferencePoint()); @@ -764,7 +763,7 @@ void TrackCreator::CopyTrackState(const edm4hep::TrackState & pTrackState, pando //------------------------------------------------------------------------------------------------------------------------------------------ -void TrackCreator::TrackReachesECAL(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const +void TrackCreator::TrackReachesECAL(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const { // Calculate hit position information @@ -847,7 +846,7 @@ void TrackCreator::TrackReachesECAL(edm4hep::Track *const pTrack, PandoraApi::Tr //------------------------------------------------------------------------------------------------------------------------------------------ -void TrackCreator::DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const +void TrackCreator::DefineTrackPfoUsage(const edm4hep::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const { bool canFormPfo(false); bool canFormClusterlessPfo(false); @@ -932,7 +931,7 @@ void TrackCreator::DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi: //------------------------------------------------------------------------------------------------------------------------------------------ -bool TrackCreator::PassesQualityCuts(edm4hep::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const +bool TrackCreator::PassesQualityCuts(const edm4hep::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const { // First simple sanity checks if (trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetMagnitude() < m_settings.m_minTrackECalDistanceFromIp) @@ -1009,7 +1008,7 @@ bool TrackCreator::PassesQualityCuts(edm4hep::Track *const pTrack, const Pandora //------------------------------------------------------------------------------------------------------------------------------------------ -int TrackCreator::GetNTpcHits(edm4hep::Track *const pTrack) const +int TrackCreator::GetNTpcHits(const edm4hep::Track *const pTrack) const { // ATTN //fg: hit numbers are now given in different order wrt LOI: @@ -1028,7 +1027,7 @@ int TrackCreator::GetNTpcHits(edm4hep::Track *const pTrack) const //------------------------------------------------------------------------------------------------------------------------------------------ -int TrackCreator::GetNFtdHits(edm4hep::Track *const pTrack) const +int TrackCreator::GetNFtdHits(const edm4hep::Track *const pTrack) const { // ATTN //fg: hit numbers are now given in different order wrt LOI: diff --git a/Service/GearSvc/src/GearSvc.cpp b/Service/GearSvc/src/GearSvc.cpp index e793bdbe8ac98c691ce7a6e085964d41709456f7..81c3611f63eafe0e0eb537b127b4cb44c0045a74 100644 --- a/Service/GearSvc/src/GearSvc.cpp +++ b/Service/GearSvc/src/GearSvc.cpp @@ -206,9 +206,9 @@ StatusCode GearSvc::convertVXD(dd4hep::DetElement& vxd){ double phi0=0; helpLayer thisLadder; double beryllium_ladder_block_length=0,end_electronics_half_z=0,side_band_electronics_width=0; - double rAlu=0, drAlu, rSty, drSty, dzSty, rInner, aluEndcapZ, aluHalfZ, alu_RadLen, Cryostat_dEdx; - double VXDSupportDensity, VXDSupportZeff, VXDSupportAeff, VXDSupportRadLen, VXDSupportIntLen=0; - double styDensity, styZeff, styAeff, styRadLen, styIntLen; + double rAlu=0, drAlu=0, rSty=0, drSty=0, dzSty=0, rInner=0, aluEndcapZ=0, aluHalfZ=0, alu_RadLen=0, Cryostat_dEdx=0; + double VXDSupportDensity=0, VXDSupportZeff=0, VXDSupportAeff=0, VXDSupportRadLen=0, VXDSupportIntLen=0; + double styDensity=0, styZeff=0, styAeff=0, styRadLen=0, styIntLen=0; dd4hep::Volume vxd_vol = vxd.volume(); for(int i=0;i<vxd_vol->GetNdaughters();i++){ TGeoNode* daughter = vxd_vol->GetNode(i); @@ -402,11 +402,11 @@ StatusCode GearSvc::convertVXD(dd4hep::DetElement& vxd){ int nFlexCable = 0, nFoamSpacer=0, nMetalTraces=0; int currentLayer = -1; - double tFlexCable, tFoamSpacer, tMetalTraces; - double radLFlexCable, radLFoamSpacer, radLMetalTraces; - double intLFlexCable, intLFoamSpacer, intLMetalTraces; - double dFlexCable, dFoamSpacer, dMetalTraces; - double metalZeff, metalZAeff, foamZeff, foamZAeff, flexZeff, flexZAeff; + double tFlexCable=0, tFoamSpacer=0, tMetalTraces=0; + double radLFlexCable=0, radLFoamSpacer=0, radLMetalTraces=0; + double intLFlexCable=0, intLFoamSpacer=0, intLMetalTraces=0; + double dFlexCable=0, dFoamSpacer=0, dMetalTraces=0; + double metalZeff=0, metalZAeff=0, foamZeff=0, foamZAeff=0, flexZeff=0, flexZAeff=0; for(int i=0;i<vol->GetNdaughters();i++){ TGeoNode* daughter = vol->GetNode(i); TGeoMaterial* matDaughter = daughter->GetMedium()->GetMaterial(); diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp index 53d9673eabf4eaf6e8746bd3d3f4c8b8110ef67b..fb2c1126b79293482e3c66c6ebb3ffe9681302d7 100644 --- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp +++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp @@ -138,7 +138,16 @@ AnExampleDetElemTool::ConstructSDandField() { warning() << "TimeProjectionChamberSensDetTool is not found, and default tracker SD will be used" << endmsg; } } - + else { + m_tracker_sdtool = ToolHandle<ISensDetTool>("GenericTrackerSensDetTool"); + if (m_tracker_sdtool) { + info() << "Find the GenericTrackerSensDetTool" << endmsg; + g4sd = m_tracker_sdtool->createSD(nam); + } + else { + warning() << "GenericTrackerSensDetTool is not found. " << endmsg; + } + } } } diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h index 9606d5cc22620f9fe91d33a24943f6f1256d393d..1b3a923f1f317a3c5e35b9d5d54eb30c84a0b097 100644 --- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h +++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h @@ -37,6 +37,7 @@ private: ToolHandle<ISensDetTool> m_calo_sdtool; ToolHandle<ISensDetTool> m_driftchamber_sdtool; ToolHandle<ISensDetTool> m_tpc_sdtool; + ToolHandle<ISensDetTool> m_tracker_sdtool; }; #endif diff --git a/Simulation/DetSimSD/CMakeLists.txt b/Simulation/DetSimSD/CMakeLists.txt index eed28a788b4893b6a771aa965f15759b3f2addfa..fa8ba9ef3e13d27da31d8c25763278ba795ef47c 100644 --- a/Simulation/DetSimSD/CMakeLists.txt +++ b/Simulation/DetSimSD/CMakeLists.txt @@ -13,6 +13,8 @@ gaudi_add_module(DetSimSD src/TimeProjectionChamberSensDetTool.cpp src/TimeProjectionChamberSensitiveDetector.cpp + src/GenericTrackerSensDetTool.cpp + src/GenericTrackerSensitiveDetector.cpp LINK DetSimInterface DetInterface ${DD4hep_COMPONENT_LIBRARIES} diff --git a/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..480f509aa57c563e90c032aac64abcaca4957a31 --- /dev/null +++ b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp @@ -0,0 +1,40 @@ +#include "GenericTrackerSensDetTool.h" + +#include "G4VSensitiveDetector.hh" + +#include "DD4hep/Detector.h" + +#include "GenericTrackerSensitiveDetector.h" + +#include "CLHEP/Units/SystemOfUnits.h" + +DECLARE_COMPONENT(GenericTrackerSensDetTool) + +StatusCode GenericTrackerSensDetTool::initialize() { + StatusCode sc; + debug() << "initialize() " << endmsg; + + m_geosvc = service<IGeomSvc>("GeomSvc"); + if (!m_geosvc) { + error() << "Failed to find GeomSvc." << endmsg; + return StatusCode::FAILURE; + } + + return AlgTool::initialize(); +} + +StatusCode GenericTrackerSensDetTool::finalize() { + StatusCode sc; + + return sc; +} + +G4VSensitiveDetector* GenericTrackerSensDetTool::createSD(const std::string& name) { + debug() << "createSD for " << name << endmsg; + + dd4hep::Detector* dd4hep_geo = m_geosvc->lcdd(); + + G4VSensitiveDetector* sd = new GenericTrackerSensitiveDetector(name, *dd4hep_geo); + + return sd; +} diff --git a/Simulation/DetSimSD/src/GenericTrackerSensDetTool.h b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.h new file mode 100644 index 0000000000000000000000000000000000000000..9f46d38111a8eeb6f56517b16474e4909d0aef4f --- /dev/null +++ b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.h @@ -0,0 +1,35 @@ +#ifndef GenericTrackerSensDetTool_h +#define GenericTrackerSensDetTool_h + +/* + * GenericTrackerSensDetTool is used to create Time Projection Chamber SD. + */ + +#include "GaudiKernel/AlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "DetSimInterface/ISensDetTool.h" +#include "DetInterface/IGeomSvc.h" + +#include "DD4hep/DD4hepUnits.h" + +class GenericTrackerSensDetTool: public extends<AlgTool, ISensDetTool> { + + public: + + using extends::extends; + + /// Overriding initialize and finalize + StatusCode initialize() override; + StatusCode finalize() override; + + /// Override ISensDetTool + virtual G4VSensitiveDetector* createSD(const std::string& name) override; + +private: + + // in order to initialize SD, we need to get the lcdd() + SmartIF<IGeomSvc> m_geosvc; + +}; + +#endif diff --git a/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d250079ef0a8aa5f15e50fb801b1de90c46d3a17 --- /dev/null +++ b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp @@ -0,0 +1,59 @@ +#include "GenericTrackerSensitiveDetector.h" + +#include "G4Step.hh" +#include "G4VProcess.hh" +//#include "G4SteppingManager.hh" +#include "G4SDManager.hh" +//#include "UserTrackInformation.hh" +#include "DD4hep/DD4hepUnits.h" + +GenericTrackerSensitiveDetector::GenericTrackerSensitiveDetector(const std::string& name, + dd4hep::Detector& description) + : DDG4SensitiveDetector(name, description), + m_hc(nullptr){ + + G4String CollName=name+"Collection"; + collectionName.insert(CollName); +} + +void GenericTrackerSensitiveDetector::Initialize(G4HCofThisEvent* HCE){ + m_hc = new HitCollection(GetName(), collectionName[0]); + int HCID = G4SDManager::GetSDMpointer()->GetCollectionID(m_hc); + HCE->AddHitsCollection( HCID, m_hc ); +} + +G4bool GenericTrackerSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*){ + + G4TouchableHandle touchPost = step->GetPostStepPoint()->GetTouchableHandle(); + G4TouchableHandle touchPre = step->GetPreStepPoint()->GetTouchableHandle(); + dd4hep::sim::Geant4StepHandler h(step); + dd4hep::Position prePos = h.prePos(); + dd4hep::Position postPos = h.postPos(); + dd4hep::Position direction = postPos - prePos; + dd4hep::Position position = mean_direction(prePos,postPos); + double hit_len = direction.R(); + if (hit_len > 0) { + double new_len = mean_length(h.preMom(),h.postMom())/hit_len; + direction *= new_len/hit_len; + } + dd4hep::sim::Geant4TrackerHit* hit = nullptr; + hit = new dd4hep::sim::Geant4TrackerHit(h.track->GetTrackID(), + h.track->GetDefinition()->GetPDGEncoding(), + step->GetTotalEnergyDeposit(), + h.track->GetGlobalTime()); + + if ( hit ) { + hit->cellID = getCellID( step ) ; + hit->energyDeposit = step->GetTotalEnergyDeposit(); + hit->position = position; + hit->momentum = direction; + hit->length = hit_len; + m_hc->insert(hit); + return true; + } + throw std::runtime_error("new() failed: Cannot allocate hit object"); + return false; +} + +void GenericTrackerSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE){ +} diff --git a/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.h b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.h new file mode 100644 index 0000000000000000000000000000000000000000..63257295e9cf8f4f580fbdcb246e7734d33c64ee --- /dev/null +++ b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.h @@ -0,0 +1,24 @@ +// ********************************************************* +// +// $Id: GenericTrackerSensitiveDetector.hh,v 1.0 2022/03/27 + +#ifndef GenericTrackerSensitiveDetector_h +#define GenericTrackerSensitiveDetector_h + +#include "DetSimSD/DDG4SensitiveDetector.h" +#include "DDG4/Defs.h" + +class GenericTrackerSensitiveDetector: public DDG4SensitiveDetector { + public: + GenericTrackerSensitiveDetector(const std::string& name, dd4hep::Detector& description); + + void Initialize(G4HCofThisEvent* HCE); + G4bool ProcessHits(G4Step* step, G4TouchableHistory* history); + void EndOfEvent(G4HCofThisEvent* HCE); + + protected: + + HitCollection* m_hc = nullptr; + +}; +#endif diff --git a/Utilities/KalDet/src/ild/common/MaterialDataBase.cc b/Utilities/KalDet/src/ild/common/MaterialDataBase.cc index a6b8f6e63488dd7026ad2a2f958ecf8292374966..f181b8b53de84a990f3b4351d455241e0a344bf8 100644 --- a/Utilities/KalDet/src/ild/common/MaterialDataBase.cc +++ b/Utilities/KalDet/src/ild/common/MaterialDataBase.cc @@ -205,9 +205,12 @@ void MaterialDataBase::createMaterials(const gear::GearMgr& gearMgr, IGeomSvc* g // VXD Support Material if(geoSvc){ - TMaterial* vxdsupport = geoSvc->getMaterial("VXDSupportMaterial"); - if(vxdsupport) this->addMaterial(vxdsupport, "VXDSupportMaterial"); - else std::cout << "Material VXDSupportMaterial not found" << std::endl; + //obselete + //TMaterial* vxdsupport = geoSvc->getMaterial("VXDSupportMaterial"); + //if(vxdsupport) this->addMaterial(vxdsupport, "VXDSupportMaterial"); + //else std::cout << "Material VXDSupportMaterial not found" << std::endl; + std::cout << "geoSvc should be set as NULL before new GeomSvc interface ready!" << std::endl; + exit(1); } else{ try{ diff --git a/Utilities/KalDet/src/ild/support/ILDSupportKalDetector.cc b/Utilities/KalDet/src/ild/support/ILDSupportKalDetector.cc index fe92415eb745cdfcbf883be2fd2c9ac3dc878bdb..64dd65463d1cf178c0c85e7d87bd079390591e21 100644 --- a/Utilities/KalDet/src/ild/support/ILDSupportKalDetector.cc +++ b/Utilities/KalDet/src/ild/support/ILDSupportKalDetector.cc @@ -35,7 +35,22 @@ TVKalDetector(10) std::vector<double> z, rInner, rOuter; // streamlog_out(DEBUG1) << "ILDSupportKalDetector building beampipe using GEAR " << std::endl ; if(geoSvc){ - const dd4hep::rec::ConicalSupportData* pBeamPipeData = geoSvc->getBeamPipeData(); + dd4hep::DetElement world = geoSvc->getDD4HepGeo(); + dd4hep::DetElement pipe; + const std::map<std::string, dd4hep::DetElement>& subs = world.children(); + for(std::map<std::string, dd4hep::DetElement>::const_iterator it=subs.begin();it!=subs.end();it++){ + if(it->first!="Tube") continue; + pipe = it->second; + } + dd4hep::rec::ConicalSupportData* pBeamPipeData = nullptr; + try{ + pBeamPipeData = pipe.extension<dd4hep::rec::ConicalSupportData>(); + } + catch(std::runtime_error& e){ + std::cout << e.what() << " " << pBeamPipeData << std::endl; + std::cerr << "Cannot find extension data in Beampipe!" << std::endl; + } + const std::vector<dd4hep::rec::ConicalSupportData::Section>& sections = pBeamPipeData->sections; const dd4hep::Direction& field = geoSvc->lcdd()->field().magneticField(dd4hep::Position(0,0,0)); bz = field.z()/dd4hep::tesla; diff --git a/Utilities/KalDet/src/ild/vxd/ILDVXDKalDetector.cc b/Utilities/KalDet/src/ild/vxd/ILDVXDKalDetector.cc index 5cacd3d76205a515295102ec6c6f865bd24776a4..3043a7f392acd79700a441c826b3cbd3f5f32522 100644 --- a/Utilities/KalDet/src/ild/vxd/ILDVXDKalDetector.cc +++ b/Utilities/KalDet/src/ild/vxd/ILDVXDKalDetector.cc @@ -382,7 +382,6 @@ void ILDVXDKalDetector::setupGearGeom( const gear::GearMgr& gearMgr ){ void ILDVXDKalDetector::setupGearGeom( IGeomSvc* geoSvc){ - /* dd4hep::DetElement world = geoSvc->getDD4HepGeo(); dd4hep::DetElement vxd; const std::map<std::string, dd4hep::DetElement>& subs = world.children(); @@ -398,14 +397,13 @@ void ILDVXDKalDetector::setupGearGeom( IGeomSvc* geoSvc){ std::cout << e.what() << " " << vxdData << std::endl; throw GaudiException(e.what(), "FATAL", StatusCode::FAILURE); } - */ + const dd4hep::Direction& field = geoSvc->lcdd()->field().magneticField(dd4hep::Position(0,0,0)); _bZ = field.z()/dd4hep::tesla; + + const std::vector<dd4hep::rec::ZPlanarData::LayerLayout>& layers = vxdData->layers; - const gear::ZPlanarParametersImpl* pVXDDetMain = geoSvc->getVXDParameters(); - const gear::VXDLayerLayout& pVXDLayerLayout = pVXDDetMain->getVXDLayerLayout(); - - _nLayers = pVXDLayerLayout.getNLayers(); + _nLayers = layers.size(); _VXDgeo.resize(_nLayers); //SJA:FIXME: for now the support is taken as the same size the sensitive @@ -414,16 +412,17 @@ void ILDVXDKalDetector::setupGearGeom( IGeomSvc* geoSvc){ // for a significant distance for( int layer=0; layer < _nLayers; ++layer){ - _VXDgeo[layer].nLadders = pVXDLayerLayout.getNLadders(layer); - _VXDgeo[layer].phi0 = pVXDLayerLayout.getPhi0(layer); + const dd4hep::rec::ZPlanarData::LayerLayout& thisLayer = layers[layer]; + _VXDgeo[layer].nLadders = thisLayer.ladderNumber; + _VXDgeo[layer].phi0 = thisLayer.phi0; _VXDgeo[layer].dphi = 2*M_PI / _VXDgeo[layer].nLadders; - _VXDgeo[layer].senRMin = pVXDLayerLayout.getSensitiveDistance(layer); - _VXDgeo[layer].supRMin = pVXDLayerLayout.getLadderDistance(layer); - _VXDgeo[layer].length = pVXDLayerLayout.getSensitiveLength(layer) * 2.0 ; // note: gear for historical reasons uses the halflength - _VXDgeo[layer].width = pVXDLayerLayout.getSensitiveWidth(layer); - _VXDgeo[layer].offset = pVXDLayerLayout.getSensitiveOffset(layer); - _VXDgeo[layer].senThickness = pVXDLayerLayout.getSensitiveThickness(layer); - _VXDgeo[layer].supThickness = pVXDLayerLayout.getLadderThickness(layer); + _VXDgeo[layer].senRMin = thisLayer.distanceSensitive; + _VXDgeo[layer].supRMin = thisLayer.distanceSupport; + _VXDgeo[layer].length = thisLayer.zHalfSensitive * 2.0 ; // note: gear for historical reasons uses the halflength + _VXDgeo[layer].width = thisLayer.widthSensitive; + _VXDgeo[layer].offset = thisLayer.offsetSensitive; + _VXDgeo[layer].senThickness = thisLayer.thicknessSensitive; + _VXDgeo[layer].supThickness = thisLayer.thicknessSupport; //std::cout << layer << ": " << _VXDgeo[layer].nLadders << " " << _VXDgeo[layer].phi0 << " " << _VXDgeo[layer].dphi << " " << _VXDgeo[layer].senRMin // << " " << _VXDgeo[layer].supRMin << " " << _VXDgeo[layer].length << " " << _VXDgeo[layer].width << " " << _VXDgeo[layer].offset // << " " << _VXDgeo[layer].senThickness << " " << _VXDgeo[layer].supThickness << std::endl; @@ -432,26 +431,20 @@ void ILDVXDKalDetector::setupGearGeom( IGeomSvc* geoSvc){ // layer, this can optionally be changed, e.g. in the case of the FPCCD where the // epitaxial layer is 15 mu thick (in a 50 mu wafer) _relative_position_of_measurement_surface = 0.5 ; + // Cryostat - try { - _vxd_Cryostat.alRadius = geoSvc->getDetParameter("VXDInfra","CryostatAlRadius"); - _vxd_Cryostat.alThickness = geoSvc->getDetParameter("VXDInfra","CryostatAlThickness"); - _vxd_Cryostat.alInnerR = geoSvc->getDetParameter("VXDInfra","CryostatAlInnerR"); - _vxd_Cryostat.alZEndCap = geoSvc->getDetParameter("VXDInfra","CryostatAlZEndCap"); - _vxd_Cryostat.alHalfZ = geoSvc->getDetParameter("VXDInfra","CryostatAlHalfZ"); + // FIXME not support by ZPlanarData, not install in current CEPC + //_vxd_Cryostat.shellInnerR = vxdData->rInnerShell; + //_vxd_Cryostat.shellThickness = vxdData->rOuterShell; + //_vxd_Cryostat.shelllHalfZ = vxdData->zHalfShell; + //_vxd_Cryostat.alRadius = geoSvc->getDetParameter("VXDInfra","CryostatAlRadius"); + //_vxd_Cryostat.alThickness = geoSvc->getDetParameter("VXDInfra","CryostatAlThickness"); + //_vxd_Cryostat.alInnerR = geoSvc->getDetParameter("VXDInfra","CryostatAlInnerR"); + //_vxd_Cryostat.alZEndCap = geoSvc->getDetParameter("VXDInfra","CryostatAlZEndCap"); + //_vxd_Cryostat.alHalfZ = geoSvc->getDetParameter("VXDInfra","CryostatAlHalfZ"); + _vxd_Cryostat.exists = false; - _vxd_Cryostat.shellInnerR = pVXDDetMain->getShellInnerRadius(); - _vxd_Cryostat.shellThickness = pVXDDetMain->getShellOuterRadius() - _vxd_Cryostat.shellInnerR; - _vxd_Cryostat.shelllHalfZ = pVXDDetMain->getShellHalfLength(); - - _vxd_Cryostat.exists = true; - //std::cout << "VXDInfra: " << _vxd_Cryostat.alRadius << " " << _vxd_Cryostat.alThickness << " " << _vxd_Cryostat.alInnerR << " " << _vxd_Cryostat.alZEndCap << " " - // << _vxd_Cryostat.alHalfZ << " " << _vxd_Cryostat.shellInnerR << " " << _vxd_Cryostat.shellThickness << " " << _vxd_Cryostat.shelllHalfZ << std::endl; - } - catch (std::runtime_error& e) { - std::cout << e.what() << std::endl ; - _vxd_Cryostat.exists = false; - - } + //std::cout << "VXDInfra: " << _vxd_Cryostat.alRadius << " " << _vxd_Cryostat.alThickness << " " << _vxd_Cryostat.alInnerR << " " << _vxd_Cryostat.alZEndCap << " " + // << _vxd_Cryostat.alHalfZ << " " << _vxd_Cryostat.shellInnerR << " " << _vxd_Cryostat.shellThickness << " " << _vxd_Cryostat.shelllHalfZ << std::endl; }