Skip to content
Snippets Groups Projects
Commit 02db3ed6 authored by Whitney Armstrong's avatar Whitney Armstrong
Browse files

Merge branch 'master' into 'master'

Electron Endcap ECAL

See merge request !29
parents 230072bf 0fc4e87d
Branches
Tags
No related merge requests found
......@@ -33,6 +33,8 @@ dd4hep_add_plugin(GenDetectors
calorimeters/src/EcalBarrel_geo.cpp
calorimeters/src/PolyhedraEndcapCalorimeter3_geo.cpp
calorimeters/src/HexagonalShashlykSamplingECAL_geo.cpp
calorimeters/src/EndcapECAL_geo.cpp
calorimeters/src/CrystalEndcapECAL_geo.cpp
beamline/src/Beampipe_geo.cpp
pid/src/GenericRICH_geo.cpp
pid/src/HexagonalScintPreShower_geo.cpp
......
<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">
<!-- Some information about detector -->
<info name="Electron_Endcap_EMcal_PbWO4_example" title="Electron Endcap EMCAL detector example"
author="Jihee Kim"
url="https://eicweb.phy.anl.gov/EIC/NPDet"
status="development"
version="v1.1 2020-03-31">
<comment>Electron Endcap EMCAL detector</comment>
</info>
<!-- Use DD4hep elements and materials definitions -->
<includes>
<gdmlFile ref="elements.xml"/>
<gdmlFile ref="materials.xml"/>
</includes>
<!-- Define the dimensions of the world volume -->
<define>
<constant name="world_side" value="10*m"/>
<constant name="world_x" value="world_side"/>
<constant name="world_y" value="world_side"/>
<constant name="world_z" value="world_side"/>
<constant name="CrossingAngle" value="0.020*rad"/>
<constant name="tracker_region_zmax" value="5 * m"/>
<constant name="tracker_region_rmax" value="5 * m"/>
<constant name="tracking_region_radius" value="1269 * mm"/>
<constant name="tracking_region_zmax_orig" value="1684 * mm"/>
<constant name="trackerZScale" value="1"/>
<constant name="tracking_region_zmax" value="tracking_region_zmax_orig * trackerZScale"/>
<constant name="CaloSides" value="12"/>
<constant name="CaloInnerRadius" value="0.1 * tracking_region_zmax"/>
<constant name="EcalBarrel_rmin" value="tracking_region_radius + 1 * mm"/>
<constant name="EcalEndcap_zmin" value="tracking_region_zmax + 1 * mm"/>
<constant name="EcalThinLayers" value="20"/>
<constant name="EcalThickLayers" value="10"/>
<constant name="EcalSiliconThickness" value="0.32 * mm"/>
<constant name="EcalCopperThickness" value="0.05 * mm"/>
<constant name="EcalKaptonThickness" value="0.3 * mm"/>
<constant name="EcalAir1Thickness" value="0.33 * mm"/>
<constant name="EcalAir2Thickness" value="0.25 * mm"/>
<constant name="EcalThinTungstenThickness" value="2.5 * mm"/>
<constant name="EcalThickTungstenThickness" value="5 * mm"/>
<constant name="EcalThickness" value="(EcalThinLayers + EcalThickLayers + 1) * (EcalSiliconThickness + EcalCopperThickness + EcalKaptonThickness + EcalAir1Thickness) + (EcalThinLayers + EcalThickLayers) * EcalAir2Thickness + EcalThinLayers * EcalThinTungstenThickness + EcalThickLayers * EcalThickTungstenThickness"/>
<!-- Added for Endcap -->
<constant name="EcalEndcap_ID" value="7"/>
<constant name="EcalEndcap_rmin" value="EcalBarrel_rmin + EcalThickness + 1 * mm"/>
<constant name="EcalEndcap_rmax" value="EcalEndcap_rmin + EcalThickness + 1 * mm"/>
<!-- -->
<constant name="HcalBarrel_rmin" value="EcalBarrel_rmin + EcalThickness + 1 * mm"/>
<constant name="HcalEndcap_zmin" value="EcalEndcap_zmin + EcalThickness + 1 * mm"/>
<constant name="HcalLayers" value="30"/>
<constant name="HcalSteelThickness" value="1.89 * cm"/>
<constant name="HcalPyrexThickness" value="1.1 * mm"/>
<constant name="HcalRPCGasThickness" value="1.2 * mm"/>
<constant name="HcalG10Thickness" value="3 * mm"/>
<constant name="HcalAirThickness" value="1.6 * mm"/>
<constant name="HcalThickness" value="HcalLayers * (HcalSteelThickness + 2 * HcalPyrexThickness + HcalRPCGasThickness + HcalG10Thickness + HcalAirThickness)"/>
</define>
<limits>
<limitset name="cal_limits">
<limit name="step_length_max" particles="*" value="5.0" unit="mm" />
</limitset>
<limitset name="SimpleRomanPotRegionLimitSet">
<limit name="step_length_max" particles="*" value="1.0" unit="mm" />
<limit name="track_length_max" particles="*" value="1.0" unit="mm" />
<limit name="time_max" particles="*" value="0.1" unit="ns" />
<limit name="ekin_min" particles="*" value="0.001" unit="MeV" />
<limit name="range_min" particles="*" value="0.1" unit="mm" />
</limitset>
</limits>
<regions>
<region name="SimpleRomanPotRegion" eunit="MeV" lunit="mm" cut="0.0001" threshold="0.0001">
<limitsetref name="SimpleRomanPotRegionLimitSet"/>
</region>
</regions>
<!-- Common Generic visualization attributes -->
<comment>Common Generic visualization attributes</comment>
<display>
<vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/>
<vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/>
<vis name="GreenVis" alpha="0.5" r= "0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="RedVis" alpha="0.5" r= "1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="BlueVis" alpha="0.5" r= "0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="OrangeVis" alpha="0.5" r= "1.0" g="0.45" b="0.0" showDaughters="true" visible="true"/>
<vis name="RedGreenVis" alpha="0.5" r= "1.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="BlueGreenVis" alpha="0.5" r= "0.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="PurpleVis" alpha="0.5" r= "1.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="DoubleRedG" alpha="0.5" r= "2.0" g=".10" b="0.0" showDaughters="true" visible="true"/>
<vis name="RBG015" alpha="0.5" r= "0.0" g=".2" b="1.0" showDaughters="true" visible="true"/>
<vis name="RBG510" alpha="0.5" r= "1.0" g=".2" b="0.0" showDaughters="true" visible="true"/>
<vis name="RBG" alpha="0.5" r= "1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="GrayVis" alpha="0.5" r= "0.75" g="0.75" b="0.75" showDaughters="true" visible="true"/>
<!-- Added -->
<vis name="EcalBarrelVis" alpha="1.0" r="1.0" g="1.0" b="0.0" showDaughters="true" visible="false"/>
<vis name="EcalStaveVis" alpha="1.0" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="EcalLayerVis" alpha="1.0" r="0.8" g="0.8" b="0.0" showDaughters="true" visible="true"/>
<vis name="EcalSensitiveVis" alpha="1.0" r="0.7" g="0.3" b="0.0" showDaughters="false" visible="true"/>
<vis name="EcalAbsorberVis" alpha="1.0" r="0.4" g="0.4" b="0.0" showDaughters="false" visible="true"/>
<vis name="EcalEndcapVis" alpha="1.0" r="0.77" g="0.74" b="0.86" showDaughters="true" visible="true"/>
<!-- -->
</display>
<!-- Define detector -->
<detectors>
<detector id="1" name="ForwardElectronECAL" type="CrystalEndcapECAL" readout="EcalEndcapHits" vis="RedVis">
<dimensions rmin="15.0*cm" rmax="60.0*cm" zmin="-30.0*cm" zmax="30.0*cm"/>
<comment>Electromagnetic Calorimeter Endcaps</comment>
</detector>
</detectors>
<!-- Definition of the readout segmentation/definition -->
<readouts>
<readout name="EcalEndcapHits">
<segmentation type="CartesianGridXY" grid_size_x="3.5*cm" grid_size_y="3.5*cm" />
<id>system:8,sector:4,module:20,layer:6,x:48:-8,y:-8</id>
</readout>
</readouts>
<plugins>
<plugin name="InstallSurfaceManager"/>
</plugins>
<fields>
<field name="GlobalSolenoid" type="solenoid"
inner_field="4.0*tesla"
outer_field="-0.6*tesla"
zmax="3*m"
outer_radius="2*m">
</field>
</fields>
</lccdd>
<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">
<!-- Some information about detector -->
<info name="Electron_Endcap_EMcal_PbWO4_example" title="Electron Endcap EMCAL detector example"
author="Jihee Kim"
url="https://eicweb.phy.anl.gov/EIC/NPDet"
status="development"
version="v1.0 2020-03-26">
<comment>Electron Endcap EMCAL detector</comment>
</info>
<!-- Use DD4hep elements and materials definitions -->
<includes>
<gdmlFile ref="elements.xml"/>
<gdmlFile ref="materials.xml"/>
</includes>
<!-- Define the dimensions of the world volume -->
<define>
<constant name="world_side" value="10*m"/>
<constant name="world_x" value="world_side"/>
<constant name="world_y" value="world_side"/>
<constant name="world_z" value="world_side"/>
<constant name="CrossingAngle" value="0.020*rad"/>
<constant name="tracking_region_radius" value="1269 * mm"/>
<constant name="tracking_region_zmax_orig" value="1684 * mm"/>
<constant name="trackerZScale" value="1"/>
<constant name="tracking_region_zmax" value="tracking_region_zmax_orig * trackerZScale"/>
<constant name="CaloSides" value="12"/>
<constant name="CaloInnerRadius" value="0.1 * tracking_region_zmax"/>
<constant name="EcalBarrel_rmin" value="tracking_region_radius + 1 * mm"/>
<constant name="EcalEndcap_zmin" value="tracking_region_zmax + 1 * mm"/>
<constant name="EcalThinLayers" value="20"/>
<constant name="EcalThickLayers" value="10"/>
<constant name="EcalSiliconThickness" value="0.32 * mm"/>
<constant name="EcalCopperThickness" value="0.05 * mm"/>
<constant name="EcalKaptonThickness" value="0.3 * mm"/>
<constant name="EcalAir1Thickness" value="0.33 * mm"/>
<constant name="EcalAir2Thickness" value="0.25 * mm"/>
<constant name="EcalThinTungstenThickness" value="2.5 * mm"/>
<constant name="EcalThickTungstenThickness" value="5 * mm"/>
<constant name="EcalThickness" value="(EcalThinLayers + EcalThickLayers + 1) * (EcalSiliconThickness + EcalCopperThickness + EcalKaptonThickness + EcalAir1Thickness) + (EcalThinLayers + EcalThickLayers) * EcalAir2Thickness + EcalThinLayers * EcalThinTungstenThickness + EcalThickLayers * EcalThickTungstenThickness"/>
<!-- Added for Endcap -->
<constant name="EcalEndcap_ID" value="7"/>
<constant name="EcalEndcap_rmin" value="EcalBarrel_rmin + EcalThickness + 1 * mm"/>
<constant name="EcalEndcap_rmax" value="EcalEndcap_rmin + EcalThickness + 1 * mm"/>
<!-- -->
<constant name="HcalBarrel_rmin" value="EcalBarrel_rmin + EcalThickness + 1 * mm"/>
<constant name="HcalEndcap_zmin" value="EcalEndcap_zmin + EcalThickness + 1 * mm"/>
<constant name="HcalLayers" value="30"/>
<constant name="HcalSteelThickness" value="1.89 * cm"/>
<constant name="HcalPyrexThickness" value="1.1 * mm"/>
<constant name="HcalRPCGasThickness" value="1.2 * mm"/>
<constant name="HcalG10Thickness" value="3 * mm"/>
<constant name="HcalAirThickness" value="1.6 * mm"/>
<constant name="HcalThickness" value="HcalLayers * (HcalSteelThickness + 2 * HcalPyrexThickness + HcalRPCGasThickness + HcalG10Thickness + HcalAirThickness)"/>
</define>
<limits>
<limitset name="cal_limits">
<limit name="step_length_max" particles="*" value="5.0" unit="mm" />
</limitset>
<limitset name="SimpleRomanPotRegionLimitSet">
<limit name="step_length_max" particles="*" value="1.0" unit="mm" />
<limit name="track_length_max" particles="*" value="1.0" unit="mm" />
<limit name="time_max" particles="*" value="0.1" unit="ns" />
<limit name="ekin_min" particles="*" value="0.001" unit="MeV" />
<limit name="range_min" particles="*" value="0.1" unit="mm" />
</limitset>
</limits>
<regions>
<region name="SimpleRomanPotRegion" eunit="MeV" lunit="mm" cut="0.0001" threshold="0.0001">
<limitsetref name="SimpleRomanPotRegionLimitSet"/>
</region>
</regions>
<!-- Common Generic visualization attributes -->
<comment>Common Generic visualization attributes</comment>
<display>
<vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/>
<vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/>
<vis name="GreenVis" alpha="0.5" r= "0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="RedVis" alpha="0.0" r= "1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="BlueVis" alpha="0.0" r= "0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="OrangeVis" alpha="0.5" r= "1.0" g="0.45" b="0.0" showDaughters="true" visible="true"/>
<vis name="RedGreenVis" alpha="0.5" r= "1.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="BlueGreenVis" alpha="0.5" r= "0.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="PurpleVis" alpha="0.5" r= "1.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="DoubleRedG" alpha="0.5" r= "2.0" g=".10" b="0.0" showDaughters="true" visible="true"/>
<vis name="RBG015" alpha="0.5" r= "0.0" g=".2" b="1.0" showDaughters="true" visible="true"/>
<vis name="RBG510" alpha="0.5" r= "1.0" g=".2" b="0.0" showDaughters="true" visible="true"/>
<vis name="RBG" alpha="0.5" r= "1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="GrayVis" alpha="0.5" r= "0.75" g="0.75" b="0.75" showDaughters="true" visible="true"/>
<!-- Added -->
<vis name="EcalBarrelVis" alpha="1.0" r="1.0" g="1.0" b="0.0" showDaughters="true" visible="false"/>
<vis name="EcalStaveVis" alpha="1.0" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="EcalLayerVis" alpha="1.0" r="0.8" g="0.8" b="0.0" showDaughters="true" visible="true"/>
<vis name="EcalSensitiveVis" alpha="1.0" r="0.7" g="0.3" b="0.0" showDaughters="false" visible="true"/>
<vis name="EcalAbsorberVis" alpha="1.0" r="0.4" g="0.4" b="0.0" showDaughters="false" visible="true"/>
<vis name="EcalEndcapVis" alpha="1.0" r="0.77" g="0.74" b="0.86" showDaughters="true" visible="true"/>
<!-- -->
</display>
<!-- Define detector -->
<detectors>
<detector id="EcalEndcap_ID" name="EcalEndcap" type="EndcapECAL" reflect="true" readout="EcalEndcapHits" vis="RedVis" calorimeterType="EM_ENDCAP">
<comment>Electromagnetic Calorimeter Endcaps</comment>
<dimensions numsides="(int) CaloSides" zmin="EcalEndcap_zmin" rmin="EcalEndcap_rmin" rmax="EcalEndcap_rmax" />
<layer repeat="70" vis="EcalEndcapVis">
<slice material = "TungstenDens24" thickness = "0.25*cm" />
<slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
<slice material = "Air" thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
</layer>
</detector>
<detector id="3" name="EcalBarrel" type="EcalBarrel" readout="EcalBarrelHits" vis="EcalBarrelVis" calorimeterType="EM_BARREL">
<comment>Electromagnetic Calorimeter Barrel</comment>
<dimensions numsides="(int) CaloSides" rmin="EcalBarrel_rmin" z="HcalEndcap_zmin*2" />
<staves vis="EcalStaveVis"/>
<layer repeat="1" vis="EcalLayerVis">
<slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
<slice material = "Copper" thickness = "0.005*cm" vis="EcalAbsorberVis"/>
<slice material = "Kapton" thickness = "0.030*cm" vis="EcalAbsorberVis"/>
<slice material = "Air" thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
</layer>
<layer repeat="20" vis="EcalLayerVis">
<slice material = "TungstenDens24" thickness = "0.25*cm" vis="EcalAbsorberVis"/>
<slice material = "Air" thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
<slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
<slice material = "Copper" thickness = "0.005*cm" vis="EcalAbsorberVis"/>
<slice material = "Kapton" thickness = "0.030*cm" vis="EcalAbsorberVis"/>
<slice material = "Air" thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
</layer>
<layer repeat="10" vis="EcalLayerVis">
<slice material = "TungstenDens24" thickness = "0.5*cm" vis="EcalAbsorberVis"/>
<slice material = "Air" thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
<slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
<slice material = "Copper" thickness = "0.005*cm" vis="EcalAbsorberVis"/>
<slice material = "Kapton" thickness = "0.030*cm" vis="EcalAbsorberVis"/>
<slice material = "Air" thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
</layer>
</detector>
</detectors>
<!-- Definition of the readout segmentation/definition -->
<readouts>
<readout name="EcalEndcapHits">
<segmentation type="CartesianGridXY" grid_size_x="3.5" grid_size_y="3.5" />
<id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
</readout>
<readout name="EcalBarrelHits">
<segmentation type="CartesianGridXY" grid_size_x="3.5 * mm" grid_size_y="3.5 * mm"/>
<id>system:6,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
</readout>
</readouts>
<plugins>
<plugin name="InstallSurfaceManager"/>
</plugins>
<fields>
<field name="GlobalSolenoid" type="solenoid"
inner_field="4.0*tesla"
outer_field="-0.6*tesla"
zmax="3*m"
outer_radius="2*m">
</field>
</fields>
</lccdd>
......@@ -178,4 +178,11 @@
<D value="0.186" unit="g / cm3"/>
<fraction n="1.0" ref="SiliconCarbide"/>
</material>
<material name="PbWO4">
<D type="density" value="8.3" unit="g / cm3"/>
<composite n="1" ref="Pb"/>
<composite n="1" ref="W"/>
<composite n="4" ref="O"/>
</material>
</materials>
//==========================================================================
// Crystal Endcap EM Calorimeter Detector implementation
//--------------------------------------------------------------------------
//
// Authors : W.Armstrong
//
//==========================================================================
// J.KIM 2020-04-01
// Added box assembly of volumes
//==========================================================================
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include <math.h>
using namespace std;
using namespace dd4hep;
using namespace dd4hep::detail;
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
xml_det_t x_det = e;
xml_dim_t dim = x_det.dimensions();
int det_id = x_det.id();
string det_name = x_det.nameStr();
Material PbWO4 = description.material("PbWO4");
double rmin = dim.rmin();
double rmax = dim.rmax();
double zmin = dim.zmin();
double zmax = dim.zmax();
double thickness = zmax - zmin;
double z_pos = zmin + thickness / 2.0;
Assembly assembly(det_name);
DetElement endcap_DE(det_name,det_id);
// Create a tube to represent the calorimeter
Tube tube(rmin, rmax, thickness / 2.0);
Volume Vol("tube_volume", tube, PbWO4);
//auto PV = assembly.placeVolume(Vol, Position(0.0, 0.0, 0.0));
//PV.addPhysVolID("layer", 0);
//sens.setType("calorimeter");
//Vol.setSensitiveDetector(sens);
// Tube is filled with box-shaped crystals forming a grid.
Assembly box_assembly("box_assembly");
PlacedVolume pv_box;
// Box-shaped crystal dimension
double box_x_width = 2*cm;
double box_y_width = 2*cm;
double box_z_length = 60.5*cm;
// Gap between box-shaped crystals
double offset_x = 1*mm;
double offset_y = 1*mm;
// Number of crystals in a grid
int nx = floor(rmax/box_x_width);
int ny = floor(rmax/box_y_width);
// X or Y spacing increasement
double x_spacing = box_x_width + offset_x;
double y_spacing = box_y_width + offset_y;
// initial positions in X or Y.
double pos_x = 0*cm;
double pos_y = 0*cm;
// Create Box and Volume
Box box(box_x_width/2.0, box_y_width/2.0, box_z_length/2.0);
Volume vol("box_volume", box, PbWO4);
////////////////////////////////////////////////////////////////////////////////////
// Divide tube into 4 sections; top left, top right, bottom left, and bottom right
////////////////////////////////////////////////////////////////////////////////////
// Top left
////////////////////////////////////////////////////////////////////////////////////
int i_module = 0;
for(int iy=0; iy<ny-1; iy++){
for(int ix=0; ix<nx; ix++){
double x_start = box_x_width/2.0;
if(ix==0)
{
pos_x = x_start;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
else
{
// Move to +X
pos_x += x_spacing;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) < rmax && sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin)
{
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
pv_box.addPhysVolID("sector",1).addPhysVolID("module",i_module);
sens.setType("calorimeter");
vol.setSensitiveDetector(sens);
}
// Move to +Y
pos_y += y_spacing;
}
////////////////////////////////////////////////////////////////////////////////////
// Top right
////////////////////////////////////////////////////////////////////////////////////
// Initialize position in Y
pos_y = 0.0;
i_module=0;
for(int iy=0; iy<ny-1; iy++){
for(int ix=0; ix<nx; ix++){
double x_start = box_x_width/2.0 + offset_x;
if(ix==0)
{
pos_x = - x_start;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
else
{
// Move to -X
pos_x -= x_spacing;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) < rmax && sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
pv_box.addPhysVolID("sector",2).addPhysVolID("module",i_module);
sens.setType("calorimeter");
vol.setSensitiveDetector(sens);
}
// Move to +Y
pos_y += y_spacing;
}
////////////////////////////////////////////////////////////////////////////////////
// Bottom left
////////////////////////////////////////////////////////////////////////////////////
// It's below the first row of the section of Top left
// That's why ny goes up to ny -2 (the first row of Bottom left starts one row less)
pos_y = -y_spacing;
i_module=0;
for(int iy=0; iy<ny-2; iy++){
for(int ix=0; ix<nx; ix++){
double x_start = box_x_width/2.0;
if(ix==0)
{
pos_x = x_start;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
else
{
// Move to +X
pos_x += x_spacing;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) < rmax && sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
pv_box.addPhysVolID("sector",3).addPhysVolID("module",i_module);
sens.setType("calorimeter");
vol.setSensitiveDetector(sens);
}
// Move to -Y
pos_y -= y_spacing;
}
////////////////////////////////////////////////////////////////////////////////////
// Bottom right
////////////////////////////////////////////////////////////////////////////////////
// Again it's below the first row of the section of Top left
// That's why ny goes up to ny -2 (the first row of Bottom left starts one row less)
pos_y = -y_spacing;
i_module=0;
for(int iy=0; iy<ny-2; iy++){
for(int ix=0; ix<nx; ix++)
{
double x_start = box_x_width/2.0 + offset_x;
if(ix==0)
{
pos_x = - x_start;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
else
{
// Move to -X
pos_x -= x_spacing;
if(sqrt((pos_x*pos_x) + (pos_y*pos_y)) < rmax && sqrt((pos_x*pos_x) + (pos_y*pos_y)) > rmin){
pv_box = assembly.placeVolume(vol, Position(pos_x,pos_y,0.0));
i_module++;
}
else{
continue;
}
}
pv_box.addPhysVolID("sector",4).addPhysVolID("module",i_module);
sens.setType("calorimeter");
vol.setSensitiveDetector(sens);
}
// Move to -Y
pos_y -= y_spacing;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
Volume motherVol = description.pickMotherVolume(endcap_DE);
auto pv = motherVol.placeVolume(assembly, Position(0.0, 0.0, z_pos));
pv.addPhysVolID("system", det_id);
endcap_DE.setPlacement(pv);
return endcap_DE;
}
DECLARE_DETELEMENT(CrystalEndcapECAL,create_detector)
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
//
// Specialized generic detector constructor
//
//==========================================================================
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
using namespace std;
using namespace dd4hep;
using namespace dd4hep::detail;
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
xml_det_t x_det = e;
xml_dim_t dim = x_det.dimensions();
int det_id = x_det.id();
bool reflect = x_det.reflect(true);
string det_name = x_det.nameStr();
Material air = description.air();
int numsides = dim.numsides();
double rmin = dim.rmin();
double rmax = dim.rmax()*std::cos(M_PI/numsides);
double zmin = dim.zmin();
Layering layering(x_det);
double totalThickness = layering.totalThickness();
Volume endcapVol("endcap",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
DetElement endcap("endcap",det_id);
int l_num = 1;
int layerType = 0;
double layerZ = -totalThickness/2;
endcapVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
for(xml_coll_t xc(x_det,_U(layer)); xc; ++xc) {
xml_comp_t x_layer = xc;
double l_thick = layering.layer(l_num-1)->thickness();
string l_name = _toString(layerType,"layer%d");
int l_repeat = x_layer.repeat();
Volume l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
vector<PlacedVolume> sensitives;
int s_num = 1;
double sliceZ = -l_thick/2;
for(xml_coll_t xs(x_layer,_U(slice)); xs; ++xs) {
xml_comp_t x_slice = xs;
string s_name = _toString(s_num,"slice%d");
double s_thick = x_slice.thickness();
Material s_mat = description.material(x_slice.materialStr());
Volume s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
sliceZ += s_thick/2;
PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ));
s_phv.addPhysVolID("slice",s_num);
if ( x_slice.isSensitive() ) {
sens.setType("calorimeter");
s_vol.setSensitiveDetector(sens);
sensitives.push_back(s_phv);
}
sliceZ += s_thick/2;
s_num++;
}
l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
if ( l_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
for(int j=0; j<l_repeat; ++j) {
string phys_lay = _toString(l_num,"layer%d");
layerZ += l_thick/2;
DetElement layer_elt(endcap, phys_lay, l_num);
PlacedVolume pv = endcapVol.placeVolume(l_vol,Position(0,0,layerZ));
pv.addPhysVolID("layer", l_num);
layer_elt.setPlacement(pv);
for(size_t ic=0; ic<sensitives.size(); ++ic) {
PlacedVolume sens_pv = sensitives[ic];
DetElement comp_elt(layer_elt,sens_pv.volume().name(),l_num);
comp_elt.setPlacement(sens_pv);
}
layerZ += l_thick/2;
++l_num;
}
++layerType;
}
double z_pos = zmin+totalThickness/2;
PlacedVolume pv;
// Reflect it.
if ( reflect ) {
Assembly assembly(det_name);
DetElement both_endcaps(det_name,det_id);
Volume motherVol = description.pickMotherVolume(both_endcaps);
DetElement sdetA = endcap;
Ref_t(sdetA)->SetName((det_name+"_A").c_str());
DetElement sdetB = endcap.clone(det_name+"_B",x_det.id());
pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
Position(0,0,z_pos)));
pv.addPhysVolID("barrel", 1);
sdetA.setPlacement(pv);
pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,M_PI,0),
Position(0,0,-z_pos)));
pv.addPhysVolID("barrel", 2);
sdetB.setPlacement(pv);
pv = motherVol.placeVolume(assembly);
pv.addPhysVolID("system", det_id);
both_endcaps.setPlacement(pv);
both_endcaps.add(sdetA);
both_endcaps.add(sdetB);
return both_endcaps;
}
Volume motherVol = description.pickMotherVolume(endcap);
pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
Position(0,0,z_pos)));
pv.addPhysVolID("system", det_id);
pv.addPhysVolID("barrel", 1);
endcap.setPlacement(pv);
Ref_t(endcap)->SetName(det_name.c_str());
return endcap;
}
DECLARE_DETELEMENT(EndcapECAL,create_detector)
//DECLARE_DEPRECATED_DETELEMENT(EndcapECAL,create_detector)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment