diff --git a/DDExamples/ILDExDet/compact/ILDEx.xml b/DDExamples/ILDExDet/compact/ILDEx.xml index 998cfa74c39e93628eedebd06b7f532fdc7ab328..dcb9cfb942501884e6712a3cfe75582f33c95b27 100644 --- a/DDExamples/ILDExDet/compact/ILDEx.xml +++ b/DDExamples/ILDExDet/compact/ILDEx.xml @@ -53,6 +53,10 @@ <!-- constant name="Hcal_Barrel_rotation" value="0.392699075"/--> <constant name="Hcal_Barrel_rotation" value="0."/> + <constant name="Hcal_endcap_modules" value="16"/> + <constant name="Hcal_endcap_layers" value="(int) 48"/> + <constant name="Hcal_endcap_zmin" value="2650*mm"/> + <constant name="SolenoidalFieldRadius" value="Hcal_outer_radius+10.0*mm"/> </define> @@ -87,9 +91,16 @@ <vis name="LumiCalVis" showDaughters="false" visible="true"/> <vis name="HcalBarrelVis" alpha="1" r="1" g="1" b="0.1" showDaughters="true" visible="true"/> - <vis name="HcalBarrelStavesVis" alpha="1" r="1" g="0" b="0.3" showDaughters="true" visible="true"/> - <vis name="HcalBarrelLayerVis" alpha="1" r="1" g="0" b="0.5" showDaughters="true" visible="true"/> - <vis name="HcalBarrelSensorVis" alpha="1" r="1" g="1" b="0.7" showDaughters="true" visible="true"/> + <vis name="HcalBarrelStavesVis" alpha="1" r="1" g="0" b="0.3" showDaughters="true" visible="false"/> + <vis name="HcalBarrelLayerVis" alpha="1" r="1" g="0" b="0.5" showDaughters="true" visible="false"/> + <vis name="HcalBarrelSensorVis" alpha="1" r="1" g="1" b="0.7" showDaughters="true" visible="false"/> + + <vis name="HcalEndcapVis" alpha="1" r="1" g="1" b="0.1" showDaughters="true" visible="true"/> + <vis name="HcalEndcapStavesVis" alpha="1" r="1" g="0" b="0.3" showDaughters="true" visible="false"/> + <vis name="HcalEndcapLayerVis" alpha="1" r="1" g="0" b="0.5" showDaughters="true" visible="false"/> + <vis name="HcalEndcapSensorVis" alpha="1" r="1" g="1" b="0.7" showDaughters="true" visible="false"/> + <vis name="HcalEndcapAirVis" alpha="1" r="1" g="0" b="0" showDaughters="true" visible="false"/> + </display> <detectors> @@ -180,11 +191,42 @@ <dimensions numsides="(int) HcalBarrel_staves" rmin="HcalBarrel_rmin" z="HcalBarrel_zmax"/> <layer repeat="(int) HcalBarrel_layers"> - <slice material = "Air" thickness = "2.7*mm" /> + <slice material = "Polystyrene" thickness = "3.0*mm" sensitive = "yes" limits="cal_limits" vis="HcalBarrelSensorVis"/> + <slice material = "FR4" thickness = "0.7*mm" /> <slice material = "Cu" thickness = "0.1*mm" /> + <slice material = "Air" thickness = "2.7*mm" vis="HcalBarrelAirVis" /> + </layer> + </detector> + <detector id="8" name="HcalEndcap" type="AhcalEndcapCalorimeter" readout="HcalEndcapHits" calorimeterType="HAD_ENDCAP" gap="15.*mm"> + <comment>Hadron Calorimeter Endcap</comment> + + <material name="Steel235"/> + + <layer repeat="(int) Hcal_endcap_layers"> + <slice material = "Polystyrene" thickness = "3.0*mm" sensitive = "yes" limits="cal_limits" vis="HcalEndcapSensorVis"/> <slice material = "FR4" thickness = "0.7*mm" /> - <slice material = "Polystyrene" thickness = "3.0*mm" sensitive = "yes" limits="cal_limits" vis="HcalBarrelSensorVis"/> + <slice material = "Cu" thickness = "0.1*mm" /> + <slice material = "Air" thickness = "2.7*mm" vis="HcalEndcapAirVis" /> </layer> + + <dimensions numsides="(int) Hcal_endcap_modules" rmin="362.0*mm" z="Hcal_endcap_zmin"> + <dimensions id="1" y_offset= "543.5" dim_x="375.0" dim_y="1287.0" dim_z="1087.0"/> + <dimensions id="2" y_offset= "905.5" dim_x="375.0" dim_y="1287.0" dim_z="1811.0"/> + <dimensions id="3" y_offset="1086.5" dim_x="375.0" dim_y="1287.0" dim_z="2173.0"/> + <dimensions id="4" y_offset="1268.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="5" y_offset="1268.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="6" y_offset="1449.0" dim_x="375.0" dim_y="1287.0" dim_z="2898.0"/> + <dimensions id="7" y_offset="1449.0" dim_x="375.0" dim_y="1287.0" dim_z="2898.0"/> + <dimensions id="8" y_offset="1630.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="9" y_offset="1630.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="10" y_offset="1449.0" dim_x="375.0" dim_y="1287.0" dim_z="2898.0"/> + <dimensions id="11" y_offset="1449.0" dim_x="375.0" dim_y="1287.0" dim_z="2898.0"/> + <dimensions id="12" y_offset="1268.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="13" y_offset="1268.0" dim_x="375.0" dim_y="1287.0" dim_z="2536.0"/> + <dimensions id="14" y_offset="1086.5" dim_x="375.0" dim_y="1287.0" dim_z="2173.0"/> + <dimensions id="15" y_offset= "905.5" dim_x="375.0" dim_y="1287.0" dim_z="1811.0"/> + <dimensions id="16" y_offset= "543.5" dim_x="375.0" dim_y="1287.0" dim_z="1087.0"/> + </dimensions> </detector> </detectors> @@ -209,6 +251,10 @@ <segmentation type="RegularNgonCartesianGridXY" gridSizeX="30.0*mm" gridSizeY="30.0*mm" /> <id>system:6,stave:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> </readout> + <readout name="HcalEndcapHits"> + <segmentation type="GlobalGridXY" gridSizeX="3.0*cm" gridSizeY="3.0*cm" /> + <id>system:6,stave:1,module:1,endcapID:5,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> </readouts> <fields> diff --git a/DDExamples/ILDExDet/src/compact/AhcalBarrelCalorimeter_geo.cpp b/DDExamples/ILDExDet/src/compact/AhcalBarrelCalorimeter_geo.cpp index 9ba13eb3b5d5e5c4be61f02882e51e20f8973b5c..38926058bfbc6e40873c8a99b3731dcc1aebf3d1 100644 --- a/DDExamples/ILDExDet/src/compact/AhcalBarrelCalorimeter_geo.cpp +++ b/DDExamples/ILDExDet/src/compact/AhcalBarrelCalorimeter_geo.cpp @@ -56,9 +56,10 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) double Hcal_lateral_structure_thickness = lcdd.constant<double>("Hcal_lateral_structure_thickness"); double Hcal_layer_air_gap = lcdd.constant<double>("Hcal_layer_air_gap"); double Hcal_back_plate_thickness = lcdd.constant<double>("Hcal_back_plate_thickness"); - double totalThickness_Hcal_Barrel = (Hcal_radiator_thickness + Hcal_chamber_thickness) - * HcalBarrel_layers + Hcal_back_plate_thickness; - double Hcal_module_radius = Hcal_inner_radius + totalThickness_Hcal_Barrel; + + double totalThickness_Hcal_Barrel = (Hcal_radiator_thickness + Hcal_chamber_thickness) + * HcalBarrel_layers + Hcal_back_plate_thickness; + double Hcal_module_radius = Hcal_inner_radius + totalThickness_Hcal_Barrel; double Hcal_Barrel_rotation = lcdd.constant<double>("Hcal_Barrel_rotation"); @@ -72,13 +73,22 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) // ========================================================================== // Hcal Barrel module shapers - PolyhedraRegular polyhedra_shaper("polyhedra",numSides,Hcal_inner_radius,Hcal_module_radius,detZ*2); - Tube tube_shaper(0.0,Hcal_outer_radius, detZ, 0.0, 2.0*M_PI); + PolyhedraRegular polyhedra_shaper("polyhedra",numSides,Hcal_inner_radius,Hcal_module_radius,detZ*2.); + Tube tube_shaper(0.,Hcal_outer_radius, detZ, 0., 2.*M_PI); + + // keep the envelope rotation as the same as the stave + // the stave number can be changed in the compact XML. + Rotation rot(M_PI/2. - M_PI/numSides,0,0); // Create Hcal Barrel volume with material Steel235 - IntersectionSolid barrelModuleSolid(tube_shaper,polyhedra_shaper,Rotation(M_PI/numSides,0,0)); + IntersectionSolid barrelModuleSolid(tube_shaper,polyhedra_shaper,rot); + Volume envelopeVol(det_name+"_envelope",barrelModuleSolid,Steel235); + // Set envelope volume attributes. + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + // ========= Create Hcal Barrel Chmaber (i.e. Layers) ======================= // It will be the sub volume for placing the slices. // Itself will be placed into the Hcal Barrel envelope. @@ -86,26 +96,23 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) // create Layer (air) and place the slices (Polystyrene,Cu,FR4,air) into it. // place the Layer into the HcalBarrel envelope (Steel235). - double innerAngle = 2*M_PI/numSides; - double halfInnerAngle = innerAngle/2; - double tan_inner = std::tan(halfInnerAngle) * 2; + double innerAngle = 2.*M_PI/numSides; + double halfInnerAngle = innerAngle/2.; + double tan_inner = std::tan(halfInnerAngle) * 2.; double cos_inner = std::cos(halfInnerAngle); double innerFaceLen = (Hcal_inner_radius + Hcal_radiator_thickness) * tan_inner; - double layerOuterAngle = (M_PI-innerAngle)/2; - double layerInnerAngle = (M_PI/2 - layerOuterAngle); + double layerOuterAngle = (M_PI-innerAngle)/2.; + double layerInnerAngle = (M_PI/2. - layerOuterAngle); // First Hcal Barrel Chamber position, start after first radiator - double layer_pos_y = Hcal_inner_radius + Hcal_radiator_thickness; - double layer_dim_x = innerFaceLen/2 - gap/2; + double layer_pos_x = Hcal_inner_radius + Hcal_radiator_thickness; + double layer_dim_y = innerFaceLen/2. - gap/2.; // Create Hcal Barrel Chamber without radiator // Place into the Hcal Barrel envelope, after each radiator int layer_num = 0; - Assembly staveVol("stave"); - PlacedVolume pv; - for(xml_coll_t c(x_det,_U(layer)); c; ++c) { xml_comp_t x_layer = c; int repeat = x_layer.repeat(); // Get number of layers. @@ -117,22 +124,23 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id()); // Layer position in Z within the stave. - layer_pos_y += layer_thickness / 2.0; + layer_pos_x += layer_thickness/2.; // Active Layer box & volume - double active_layer_dim_x = layer_dim_x; - double active_layer_dim_y = (detZ-Hcal_lateral_structure_thickness)/2.; - double active_layer_dim_z = layer_thickness/2.0; + double active_layer_dim_x = layer_thickness/2.; + double active_layer_dim_y = layer_dim_y; + double active_layer_dim_z = (detZ-Hcal_lateral_structure_thickness)/2.; // The same Layer will be filled with skices, // and placed into the HcalBarrel 16 times: 8 Staves * 2 modules: TODO 32 times. Volume layer_vol(layer_name, Box(active_layer_dim_x,active_layer_dim_y,active_layer_dim_z), air); + // ========= Create sublayer slices ========================================= // Create and place the slices into Layer // ========================================================================== // Create the slices (sublayers) within the Hcal Barrel Chamber. - double slice_pos_z = -(layer_thickness / 2); + double slice_pos_x = -(layer_thickness/2.); int slice_number = 0; for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { xml_comp_t x_slice = k; @@ -141,11 +149,11 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) Material slice_material = lcdd.material(x_slice.materialStr()); DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); - slice_pos_z += slice_thickness / 2; + slice_pos_x += slice_thickness/2.; // Slice volume & box - double slice_dim_x = active_layer_dim_x - Hcal_layer_air_gap ; - Volume slice_vol(slice_name,Box(slice_dim_x,active_layer_dim_y,slice_thickness/2.0),slice_material); + double slice_dim_y = active_layer_dim_y - Hcal_layer_air_gap ; + Volume slice_vol(slice_name,Box(slice_thickness/2.,slice_dim_y,active_layer_dim_z),slice_material); if ( x_slice.isSensitive() ) { sens.setType("calorimeter"); @@ -154,11 +162,12 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) // Set region, limitset, and vis. slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); // slice PlacedVolume - pv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); - pv.addPhysVolID("slice",slice_number); - slice.setPlacement(pv); - // Increment Z position for next slice. - slice_pos_z += slice_thickness / 2; + PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(slice_pos_x,0.,0.)); + slice_phv.addPhysVolID("slice",slice_number); + + slice.setPlacement(slice_phv); + // Increment x position for next slice. + slice_pos_x += slice_thickness/2.; // Increment slice number. ++slice_number; } @@ -175,62 +184,65 @@ static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) // Acording to the number of staves and modules, // Place the same Layer into the HcalBarrel envelope // with the right position and rotation. - - // Layer physical volume. - double layer_pos_z = active_layer_dim_y + Hcal_lateral_structure_thickness; - for(int module_num=0;module_num<2;module_num++) { - layer_pos_z = (module_num==0)?layer_pos_z:-layer_pos_z; - Position l_pos(0,layer_pos_y-Hcal_inner_radius,layer_pos_z); - pv = staveVol.placeVolume(layer_vol,Transform3D(RotationX(M_PI/2),l_pos)); - // registry the ID of Layer, stave and module - pv.addPhysVolID("layer",layer_num).addPhysVolID("module",module_num); - // then setPlacement for it. - layer.setPlacement(pv); + for(int stave_num = 0; stave_num < numSides; stave_num++){ + double ds = double(stave_num); + double delte_phi = M_PI/2. - innerAngle*ds; + string stave_layer = _toString(stave_num,"stave%d_layer"); + // Layer physical volume. + double layer_pos_z = active_layer_dim_z + Hcal_lateral_structure_thickness; + for(int module_num = 0; module_num < 2; module_num++) + { + layer_pos_z = (module_num==0)?layer_pos_z:-layer_pos_z; + PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol, + Transform3D(Rotation(delte_phi,0.,0.), + Translation3D(layer_pos_x*std::cos(delte_phi), + layer_pos_x*std::sin(delte_phi), + layer_pos_z))); + + // registry the ID of Layer, stave and module + layer_phv.addPhysVolID("layer",layer_num); + layer_phv.addPhysVolID("stave",stave_num); + layer_phv.addPhysVolID("module",module_num); + // then setPlacement for it. + layer.setPlacement(layer_phv); + + } } - + + // ===== Prepare for next layer (i.e. next Chamber) ========================= // Prepare the chamber placement position and the chamber dimension // ========================================================================== // Prepare for next Layer - // Increment the layer_pos_y, and calculate the next layer_dim_x + // Increment the layer_pos_x, and calculate the next layer_dim_y // Place Hcal Barrel Chamber after each radiator - layer_pos_y += layer_thickness / 2; - layer_pos_y += Hcal_radiator_thickness; + layer_pos_x += layer_thickness/2.; + layer_pos_x += Hcal_radiator_thickness; // Increment the layer X dimension. - if((layer_pos_y + layer_thickness ) < (Hcal_outer_radius - Hcal_back_plate_thickness)* cos_inner) - layer_dim_x += (layer_thickness + Hcal_radiator_thickness) * std::tan(layerInnerAngle); + if((layer_pos_x + layer_thickness ) < (Hcal_outer_radius - Hcal_back_plate_thickness)* cos_inner) + layer_dim_y += (layer_thickness + Hcal_radiator_thickness) * std::tan(layerInnerAngle); else - layer_dim_x = std::sqrt((Hcal_outer_radius-Hcal_radiator_thickness) + layer_dim_y = std::sqrt((Hcal_outer_radius-Hcal_radiator_thickness) *(Hcal_outer_radius-Hcal_radiator_thickness) - - layer_pos_y*layer_pos_y) - gap/2; + - layer_pos_x*layer_pos_x) - gap/2.; // Increment the layer number. ++layer_num; } } - // Now place all staves - for(int stave_num=0;stave_num<numSides;stave_num++) { - double r = Hcal_inner_radius+Hcal_radiator_thickness; - double phi = (2.*M_PI/numSides)*stave_num; - Position pos(r*std::sin(phi),r*std::cos(phi),0); - pv = envelopeVol.placeVolume(staveVol,Transform3D(Rotation(phi,M_PI,0),pos)); - // registry the ID of Layer, stave and module - pv.addPhysVolID("stave",stave_num); - } // =========== Place Hcal Barrel envelope =================================== // Finally place the Hcal Barrel envelope into the world volume. // Registry the system ID. // ========================================================================== - // Set envelope volume attributes. - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); // Place Hcal Barrel volume into the world volume - pv = motherVol.placeVolume(envelopeVol,Rotation(0,0,Hcal_Barrel_rotation)); + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Rotation(0.,0.,Hcal_Barrel_rotation)); + // registry the system id - pv.addPhysVolID("system", sdet.id()); - sdet.setPlacement(pv); + env_phv.addPhysVolID("system", sdet.id()); + sdet.setPlacement(env_phv); return sdet; } diff --git a/DDExamples/ILDExDet/src/compact/AhcalEndcapCalorimeter_geo.cpp b/DDExamples/ILDExDet/src/compact/AhcalEndcapCalorimeter_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c1948276954cc6322b855554e2e941d33a1de6a --- /dev/null +++ b/DDExamples/ILDExDet/src/compact/AhcalEndcapCalorimeter_geo.cpp @@ -0,0 +1,286 @@ +//==================================================================== +// AIDA Detector description implementation +// for LDC AHCAL Endcap +//-------------------------------------------------------------------- +// +// Author : S.Lu +// +// 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 "XML/Layering.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static Ref_t create_detector(LCDD& lcdd, 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(); + string det_type = x_det.typeStr(); + Material air = lcdd.air(); + Material Steel235 = lcdd.material(x_det.materialStr()); + double gap = xml_dim_t(x_det).gap(); + // int numSides = dim.numsides(); + double detZ = dim.z(); // Hcal endcap modules z start + double Hcal_inner_radius = dim.rmin(); // Endcap cernter box hole half length: 362.0 + + // The way to reaad constant from XML/LCDD file. + //double Hcal_outer_radius = lcdd.constant<double>("Hcal_outer_radius"); // 3395.46 mm + double Hcal_radiator_thickness = lcdd.constant<double>("Hcal_radiator_thickness"); // 20.0mm + //double Hcal_chamber_thickness = lcdd.constant<double>("Hcal_chamber_thickness"); // 6.5mm + //int Hcal_endcap_layers = lcdd.constant<int>("Hcal_endcap_layers"); // 48 + // ======== Note============================================================ + // In the XML/LCDD file, make sure the above constant parameters + // are agree with the layering/slices in the detector Ahcal. + // ========================================================================== + + + double Hcal_lateral_structure_thickness = lcdd.constant<double>("Hcal_lateral_structure_thickness"); + double Hcal_layer_air_gap = lcdd.constant<double>("Hcal_layer_air_gap"); + double Hcal_endcap_zmin = lcdd.constant<double>("Hcal_endcap_zmin"); + //double Hcal_back_plate_thickness = lcdd.constant<double>("Hcal_back_plate_thickness"); + + // ========= Create Hcal Endcap Modules envelope ============================ + // Read the Endcap Modules dimensions, + // Which defined in the compact XML files. + // ========================================================================== + double dim_x[16]; + double dim_y[16]; + double dim_z[16]; + double pos_x[16]; + double pos_y[16]; + double pos_z[16]; + + int endcapID =0; + for(xml_coll_t c(x_det.child(_U(dimensions)),_U(dimensions)); c; ++c) { + + xml_comp_t l(c); + + dim_x[endcapID] = l.attr<double>(_Unicode(dim_x)); + dim_y[endcapID] = l.attr<double>(_Unicode(dim_y)); + dim_z[endcapID] = l.attr<double>(_Unicode(dim_z)); + pos_y[endcapID] = l.attr<double>(_Unicode(y_offset)); + //std::cout<<" dim_z["<<endcapID<<"]: "<< dim_z[endcapID]/2.0<<std::endl; + endcapID++; + } + + + DetElement sdet(det_name,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + + // ========= Create Hcal Endcap Modules envelope ============================ + // They will be the volume for palcing the Hcal Chamber(i.e. Layers). + // Themself will be placed into the world volume. + // ========================================================================== + + // build 16 Endcap Modules + for(int ecID=0; ecID<endcapID; ecID++) + { + // Hcal Endcap module shape + double box_half_x= dim_x[ecID]/2.0; // module width, all are same + double box_half_y= dim_y[ecID]/2.0; // total thickness, all are same + double box_half_z= dim_z[ecID]/2.0; // module length, changed, + + double x_offset = box_half_x*endcapID-box_half_x*ecID*2.0-box_half_x; + double y_offset = pos_y[ecID]; + + Box EndcapModule(box_half_x,box_half_y,box_half_z); + + // define the name of each endcap Module + string envelopeVol_name = det_name+_toString(ecID,"_EndcapModule%d"); + + Volume envelopeVol(envelopeVol_name,EndcapModule,Steel235); + + // Set envelope volume attributes. + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + + // ========= 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 (Steel235). + + // 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 = 0; + for(xml_coll_t c(x_det,_U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); // Get number of layers. + const Layer* lay = layering.layer(layer_num); // Get the layer from the layering engine. + + string layer_name = envelopeVol_name+"_layer"; + double layer_thickness = lay->thickness(); + DetElement layer(layer_name,layer_name,x_det.id()); + + // Active Layer box & volume + double active_layer_dim_x = box_half_x - Hcal_lateral_structure_thickness; + 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_layer_air_gap), + active_layer_dim_y,active_layer_dim_z), air); + + + // ========= 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; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = layer_name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = lcdd.material(x_slice.materialStr()); + DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); + + slice_pos_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); + + if ( x_slice.isSensitive() ) { + sens.setType("calorimeter"); + slice_vol.setSensitiveDetector(sens); + } + // Set region, limitset, and vis. + slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + // slice PlacedVolume + PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,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(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + + // ========= 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); + layer_phv.addPhysVolID("endcapID",ecID); + // then setPlacement for it. + layer.setPlacement(layer_phv); + + + // ===== 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; + double EndcapModule_pos_y; + double EndcapModule_pos_z = Hcal_endcap_zmin + box_half_y; + double rot_EM = 0; + + switch (stave_num) + { + case 0 : + EndcapModule_pos_x = x_offset; + EndcapModule_pos_y = y_offset; + break; + case 1 : + EndcapModule_pos_x = -x_offset; + EndcapModule_pos_y = -y_offset; + break; + } + + for(int module_num=0;module_num<2;module_num++) { + + rot_EM = (module_num==0)?(M_PI/2.0):(-M_PI/2.0); + + EndcapModule_pos_z = (module_num==0)?EndcapModule_pos_z:-EndcapModule_pos_z; + + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol, + Transform3D(Rotation(0.,0.,rot_EM), + Translation3D(EndcapModule_pos_x, + EndcapModule_pos_y, + EndcapModule_pos_z))); + + env_phv.addPhysVolID("stave",stave_num); // y: up /down + env_phv.addPhysVolID("module",module_num); // z: +/- + env_phv.addPhysVolID("system",x_det.id()); + sdet.setPlacement(env_phv); + + } + + } + + } + + + + return sdet; +} + + + + +DECLARE_DETELEMENT(AhcalEndcapCalorimeter, create_detector);