static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector sens) { typedef vector<PlacedVolume> Placements; xml_det_t x_det = e; Material air = theDetector.air(); int det_id = x_det.id(); string det_name = x_det.nameStr(); DetElement sdet (det_name,det_id); // Assembly assembly (det_name); map<string, Volume> volumes; map<string, Placements> sensitives; PlacedVolume pv; // for encoding std::string cellIDEncoding = sens.readout().idSpec().fieldDescription(); UTIL::BitField64 encoder( cellIDEncoding ); encoder.reset(); encoder[lcio::LCTrackerCellID::subdet()] = det_id; encoder[lcio::LCTrackerCellID::side()] = lcio::ILDDetID::barrel; // --- create an envelope volume and position it into the world --------------------- Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, e , sdet ) ; dd4hep::xml::setDetectorTypeFlag( e, sdet ) ; if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ; //----------------------------------------------------------------------------------- ZPlanarData* zPlanarData = new ZPlanarData() ; NeighbourSurfacesData* neighbourSurfacesData = new NeighbourSurfacesData() ; sens.setType("tracker"); //NOTE modules are what is defined in compact. Later we call a "module" as a "sensor". for(xml_coll_t mi(x_det,_U(module)); mi; ++mi) { xml_comp_t x_mod = mi; xml_comp_t m_env = x_mod.child(_U(module_envelope)); string m_nam = x_mod.nameStr(); if ( volumes.find(m_nam) != volumes.end() ) { printout(ERROR,"TrackerBarrel","Logics error in building modules."); throw runtime_error("Logic error in building modules."); } double module_thickness = 0; for(xml_coll_t incl(x_mod,_U(include)); incl; ++incl) { dd4hep::xml::DocumentHolder doc(dd4hep::xml::DocumentHandler().load(incl, incl.attr_value(_U(ref)))); xml_h includes = doc.root(); xml_det_t incl_stack = includes; for (xml_coll_t ci(incl_stack, _U(module_component)); ci; ++ci) { xml_comp_t x_comp = ci; module_thickness = module_thickness + x_comp.thickness(); } } Volume m_vol(m_nam,Box(m_env.width()/2.,m_env.length()/2.,module_thickness/2.),air); volumes[m_nam] = m_vol; m_vol.setVisAttributes(theDetector.visAttributes(x_mod.visStr())); int ncomponents = 0; //First component on top of the list is the innermost one. double position_z= -module_thickness/2.; for(xml_coll_t incl(x_mod,_U(include)); incl; ++incl) { dd4hep::xml::DocumentHolder doc(dd4hep::xml::DocumentHandler().load(incl, incl.attr_value(_U(ref)))); xml_h includes = doc.root(); xml_det_t incl_stack = includes; for (xml_coll_t ci(incl_stack, _U(module_component)); ci; ++ci, ++ncomponents) { xml_comp_t x_comp = ci; string c_nam = _toString(ncomponents, "component%d"); Box c_box(m_env.width() / 2.0, m_env.length() / 2.0, x_comp.thickness() / 2.0); Volume c_vol(c_nam, c_box, theDetector.material(x_comp.materialStr())); pv = m_vol.placeVolume(c_vol, Position(0, 0, position_z + x_comp.thickness() / 2.0)); c_vol.setRegion(theDetector, x_comp.regionStr()); c_vol.setLimitSet(theDetector, x_comp.limitsStr()); c_vol.setVisAttributes(theDetector, x_comp.visStr()); if (x_comp.isSensitive()) { // pv.addPhysVolID("wafer",wafer_number++); c_vol.setSensitiveDetector(sens); sensitives[m_nam].push_back(pv); } position_z += x_comp.thickness(); } } } for(xml_coll_t li(x_det,_U(layer)); li; ++li) { xml_comp_t x_layer = li; xml_comp_t x_layout = x_layer.child(_U(rphi_layout)); xml_comp_t z_layout = x_layer.child(_U(z_layout)); // Get the <z_layout> element. int lay_id = x_layer.id(); // int type = x_layer.type(); string m_nam = x_layer.moduleStr(); string lay_nam = _toString(x_layer.id(),"layer%d"); Assembly lay_vol (lay_nam); // Create the layer envelope volume. double phi0 = x_layout.phi0(); // Starting phi of first sensor. double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a sensor. double rc = x_layout.rc(); // Radius of the sensor center. int nphi = x_layout.nphi(); // Number of sensors in phi. double rphi_dr = x_layout.dr(); // The delta radius of every other sensor. double phi_incr = (M_PI * 2) / nphi; // Phi increment for one sensor. double phic = phi0; // Phi of the sensor center. double z0 = z_layout.z0(); // Z position of first sensor in phi. double nz = z_layout.nz(); // Number of sensors to place in z. double z_dr = z_layout.dr(); // Radial displacement parameter, of every other sensor. Volume m_env = volumes[m_nam]; DetElement lay_elt(sdet,_toString(x_layer.id(),"layer%d"),lay_id); Placements& waferVols = sensitives[m_nam]; // Z increment for sensor placement along Z axis. // Adjust for z0 at center of sensor rather than // the end of cylindrical envelope. double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0; // Starting z for sensor placement along Z axis. double sensor_z = -z0; int module_idx =0; ZPlanarData::LayerLayout thisLayer ; // Loop over the number of sensors in phi. for (int ii = 0; ii < nphi; ii++) { double dx = z_dr * std::cos(phic + phi_tilt); // Delta x of sensor position. double dy = z_dr * std::sin(phic + phi_tilt); // Delta y of sensor position. double x = rc * std::cos(phic); // Basic x sensor position. double y = rc * std::sin(phic); // Basic y sensor position. // Loop over the number of sensors in z. //Create stave FIXME disable for now string module_name = _toString(module_idx,"module%d"); // DetElement module_elt(lay_elt,module_name,module_idx); int sensor_idx = 0; for (int j = 0; j < nz; j++) { string sensor_name = _toString(sensor_idx,"sensor%d"); /////////////////// //get cellID and fill map< cellID of surface, vector of cellID of neighbouring surfaces > //encoding encoder[lcio::LCTrackerCellID::layer()] = lay_id; encoder[lcio::LCTrackerCellID::module()] = module_idx; encoder[lcio::LCTrackerCellID::sensor()] = sensor_idx; dd4hep::long64 cellID = encoder.lowWord(); // 32 bits //compute neighbours int n_neighbours_module = 1; // 1 gives the adjacent modules (i do not think we would like to change this) int n_neighbours_sensor = 1; int newmodule=0, newsensor=0; for(int imodule=-n_neighbours_module; imodule<=n_neighbours_module; imodule++){ // neighbouring modules for(int isensor=-n_neighbours_sensor; isensor<=n_neighbours_sensor; isensor++){ // neighbouring sensors if (imodule==0 && isensor==0) continue; // cellID we started with newmodule = module_idx + imodule; newsensor = sensor_idx + isensor; //compute special case at the boundary //general computation to allow (if necessary) more then adjacent neighbours (ie: +-2) if (newmodule < 0) newmodule = nphi + newmodule; if (newmodule >= nphi) newmodule = newmodule - nphi; if (newsensor < 0 || newsensor >= nz) continue; //out of the stave //encoding encoder[lcio::LCTrackerCellID::module()] = newmodule; encoder[lcio::LCTrackerCellID::sensor()] = newsensor; neighbourSurfacesData->sameLayer[cellID].push_back(encoder.lowWord()); } } /////////////////// //FIXME sensor_name = module_name + sensor_name; DetElement sens_elt(lay_elt,sensor_name,sensor_idx); // Module PhysicalVolume. Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,sensor_z)); //FIXME pv = lay_vol.placeVolume(m_env,tr); pv.addPhysVolID(_U(module), module_idx); pv.addPhysVolID(_U(sensor), sensor_idx); sens_elt.setPlacement(pv); for(size_t ic=0; ic<waferVols.size(); ++ic) { // std::cout<<"Layer: "<<lay_id<<" phiIdx: "<<ii<<" zidx: "<<j<<" wafer idx: "<<ic<<std::endl; PlacedVolume wafer_pv = waferVols[ic]; DetElement comp_elt(sens_elt,wafer_pv.volume().name(),sensor_idx); comp_elt.setPlacement(wafer_pv); ///GET GEAR INFORMATION FROM FIRST "MODULE" IN Z AND phi ///NOTE WORKS ONLY FOR ONE WAFER if (ii==0 && j==0 && ic==0){ Box mod_shape(m_env.solid()), comp_shape(wafer_pv.volume().solid()); const double* trans = comp_elt.placement()->GetMatrix()->GetTranslation(); double half_module_thickness = mod_shape->GetDZ(); double half_silicon_thickness = comp_shape->GetDZ(); double sensitive_z_position = trans[2]; double inner_thickness = half_module_thickness - sensitive_z_position; thisLayer.distanceSupport = rc ; thisLayer.offsetSupport = 0; thisLayer.thicknessSupport = inner_thickness- half_silicon_thickness; thisLayer.zHalfSupport = z0 + mod_shape->GetDY(); thisLayer.widthSupport = 2*mod_shape->GetDX(); thisLayer.distanceSensitive = rc+sensitive_z_position; thisLayer.offsetSensitive = 0. ; thisLayer.thicknessSensitive = 2*half_silicon_thickness;//Assembled along Z //Changed by Thorben Quast (same applies to zHalfSupport) //z0 = center of most right sensor, comp_shape-GetDY() = half length of one sensitive are of the module thisLayer.zHalfSensitive = z0 + comp_shape->GetDY(); thisLayer.widthSensitive = 2*comp_shape->GetDX(); thisLayer.ladderNumber = (int) nphi ; thisLayer.phi0 = phic; } } /// Increase counters etc. sensor_idx++; // Adjust the x and y coordinates of the sensor. x += dx; y += dy; // Flip sign of x and y adjustments. dx *= -1; dy *= -1; // Add z increment to get next z placement pos. sensor_z += z_incr; } module_idx++; phic += phi_incr; // Increment the phi placement of sensor. rc += rphi_dr; // Increment the center radius according to dr parameter. rphi_dr *= -1; // Flip sign of dr parameter. sensor_z = -z0; // Reset the Z placement parameter for sensor. } // Create the PhysicalVolume for the layer. pv = envelope.placeVolume(lay_vol); // Place layer in mother pv.addPhysVolID("layer", lay_id); // Set the layer ID. lay_elt.setAttributes(theDetector,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); lay_elt.setPlacement(pv); zPlanarData->layers.push_back( thisLayer ) ; } sdet.setAttributes(theDetector,envelope,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); sdet.addExtension< ZPlanarData >( zPlanarData ) ; sdet.addExtension< NeighbourSurfacesData >( neighbourSurfacesData ) ; //envelope.setVisAttributes(theDetector.invisible()); /*pv = theDetector.pickMotherVolume(sdet).placeVolume(assembly); pv.addPhysVolID("system", det_id); // Set the subdetector system ID. pv.addPhysVolID("barrel", 0); // Flag this as a barrel subdetector. sdet.setPlacement(pv);*/ return sdet; }
static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { xml_det_t x_det = element; string det_name = x_det.nameStr(); DetElement sdet( det_name,x_det.id() ); Layering layering(x_det); xml_dim_t dim = x_det.dimensions(); // --- 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 ; //----------------------------------------------------------------------------------- Material air = theDetector.air(); sens.setType("calorimeter"); //==================================================================== // // Read all the dimensions from compact.xml, user can update the value. // Use them to build a calo box prototye. // //==================================================================== double Calo_dim_x = dim.x(); double Calo_dim_y = dim.y(); double Calo_dim_z = dim.z(); printout( dd4hep::DEBUG, "building SamplingCaloBoxPrototype_v01", "Calo_dim_x : %e Calo_dim_y: %e Calo_dim_z: %e ", Calo_dim_x, Calo_dim_y, Calo_dim_z) ; //==================================================================== // // general calculated parameters // //==================================================================== //calorimeter dimensions double cal_hx = Calo_dim_x/2.0; double cal_hy = Calo_dim_y/2.0; double cal_hz = Calo_dim_z/2.0; //==================================================================== // // build sampling layers in the CaloBox // //==================================================================== int layer_num = 0; int layerType = 0; double layer_pos_z = - cal_hz; for (xml_coll_t c(x_det, _U(layer)); c; ++c) { xml_comp_t x_layer = c; int repeat = x_layer.repeat(); const Layer* lay = layering.layer(layer_num); double layer_thickness = lay->thickness(); string layer_type_name = _toString(layerType,"layerType%d"); // Loop over repeats for this layer. for (int j = 0; j < repeat; j++) { string layer_name = _toString(layer_num, "layer%d"); DetElement layer(layer_name, layer_num); // Layer box & volume Volume layer_vol(layer_type_name, Box(cal_hx, cal_hy, layer_thickness / 2), air); // Create the slices (sublayers) within the layer. 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 = _toString(slice_number, "slice%d"); double slice_thickness = x_slice.thickness(); Material slice_material = theDetector.material(x_slice.materialStr()); DetElement slice(layer, slice_name, slice_number); slice_pos_z += slice_thickness / 2; // Slice volume & box Volume slice_vol(slice_name, Box(cal_hx, cal_hy, slice_thickness / 2), slice_material); if (x_slice.isSensitive()) { sens.setType("calorimeter"); slice_vol.setSensitiveDetector(sens); } // 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; // Increment slice number. ++slice_number; } // Set region, limitset, and vis. layer_vol.setAttributes(theDetector, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); // Layer position in Z within the stave. layer_pos_z += layer_thickness / 2; // Layer physical volume. PlacedVolume layer_phv = envelope.placeVolume(layer_vol, Position(0, 0, layer_pos_z)); layer_phv.addPhysVolID("layer", layer_num); layer.setPlacement(layer_phv); // Increment the layer Z position. layer_pos_z += layer_thickness / 2; // Increment the layer number. ++layer_num; } ++layerType; } return sdet; }
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(); //unused: string det_type = x_det.typeStr(); 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>("HcalEndcap_inner_radius"); double HcalEndcap_outer_radius = theDetector.constant<double>("HcalEndcap_outer_radius"); double HcalEndcap_min_z = theDetector.constant<double>("HcalEndcap_min_z"); double HcalEndcap_max_z = theDetector.constant<double>("HcalEndcap_max_z"); double Hcal_steel_cassette_thickness = theDetector.constant<double>("Hcal_steel_cassette_thickness"); double HcalServices_outer_FR4_thickness = theDetector.constant<double>("HcalServices_outer_FR4_thickness"); double HcalServices_outer_Cu_thickness = theDetector.constant<double>("HcalServices_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(); std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); //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::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; // total thickness, all are same double box_half_z= dim_z/2.0; // module length, changed, 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 = box_half_y; double FEE_half_Z = Hcal_endcap_services_module_width/2.0; 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,FEELayer_thickness/2.0,FEE_half_Z); Volume FEELayer("FEELayer",FEELayerBox,air); Box FEELayerSteelBox(FEE_half_x,Hcal_steel_cassette_thickness/2.0,FEE_half_Z); Volume FEELayerSteel("FEELayerSteel",FEELayerSteelBox,stainless_steel); pVol = FEELayer.placeVolume(FEELayerSteel, Position(0, (-FEELayer_thickness/2.0 +Hcal_steel_cassette_thickness/2.0), 0)); Box FEELayerFR4Box(FEE_half_x,HcalServices_outer_FR4_thickness/2.0,FEE_half_Z); Volume FEELayerFR4("FEELayerFR4",FEELayerFR4Box,PCB); pVol = FEELayer.placeVolume(FEELayerFR4, Position(0, (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness +HcalServices_outer_FR4_thickness/2.0), 0)); Box FEELayerCuBox(FEE_half_x,HcalServices_outer_Cu_thickness/2.0,FEE_half_Z); Volume FEELayerCu("FEELayerCu",FEELayerCuBox,copper); pVol = FEELayer.placeVolume(FEELayerCu, Position(0, (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness+HcalServices_outer_FR4_thickness +HcalServices_outer_Cu_thickness/2.0), 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_y = - box_half_y + 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 = layer_thickness/2.0; double active_layer_dim_z = box_half_z; // 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); LayeredCalorimeterData::Layer caloLayer ; caloLayer.cellSize0 = cell_sizeX; caloLayer.cellSize1 = cell_sizeY; // ========= Create sublayer slices ========================================= // Create and place the slices into Layer // ========================================================================== // Create the slices (sublayers) within the Hcal Chamber. double slice_pos_y = -(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_y += slice_thickness / 2.0; // Slice volume & box Volume slice_vol(slice_name,Box(active_layer_dim_x,slice_thickness/2.0,active_layer_dim_z),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() ) { sens.setType("calorimeter"); slice_vol.setSensitiveDetector(sens); #if DD4HEP_VERSION_GE( 0, 15 ) //Store "inner" quantities caloLayer.inner_nRadiationLengths = nRadiationLengths; caloLayer.inner_nInteractionLengths = nInteractionLengths; caloLayer.inner_thickness = thickness_sum; //Store scintillator thickness caloLayer.sensitive_thickness = slice_thickness; #endif //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,slice_pos_y,0)); //slice_phv.addPhysVolID("slice",slice_number); slice.setPlacement(slice_phv); // Increment Z position for next slice. slice_pos_y += 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()); #if DD4HEP_VERSION_GE( 0, 15 ) //Store "outer" quantities caloLayer.outer_nRadiationLengths = nRadiationLengths; caloLayer.outer_nInteractionLengths = nInteractionLengths; caloLayer.outer_thickness = thickness_sum; #endif // ========= 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_y += layer_thickness / 2.0; PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol, Position(0,layer_pos_y,0)); // 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,layer_pos_y,0)); //----------------------------------------------------------------------------------------- if ( caloData->layers.size() < (unsigned int)repeat ) { caloLayer.distance = HcalEndcap_min_z + box_half_y + layer_pos_y - 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_y += layer_thickness / 2.0; layer_pos_y += 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_y; 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_y; 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_z + 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_z - 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/2.0):(M_PI/2.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; }