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

Added parameterized cylindrical barrel detector construction.

 - CylinderTrackerBarrel_geo can be used to define detailed modules
 which are then placed in barrel array.
 - The modules are cylindrical segments of a tube.
	modified:   compact/definitions.xml
	modified:   compact/gem_tracker_endcap.xml
	new file:   compact/mm_tracker_barrel.xml
	modified:   reference_detector.xml
	new file:   src/CylinderTrackerBarrel_geo.cpp
parent 7f6d2694
No related branches found
No related tags found
No related merge requests found
...@@ -130,12 +130,23 @@ ...@@ -130,12 +130,23 @@
<constant name="cb_CTD_Si_ID" value="74"/> <constant name="cb_CTD_Si_ID" value="74"/>
<comment> <comment>
===================
(75-84) Barrel Tracker IDs
===================
MMTrackerBarrel ID: 75
Unused IDs: 76-89
</comment>
<constant name="MMTrackerBarrel_ID" value="75"/>
<comment>
=================== ===================
(75-99) Reserved IDs (85-99) Reserved IDs
=================== ===================
Unused IDs: 75-89 Unused IDs: 85-89
TBD TBD
</comment> </comment>
<comment> <comment>
...@@ -364,8 +375,10 @@ ...@@ -364,8 +375,10 @@
The central tracking detectors are assumed to be symmtric about the origin. The central tracking detectors are assumed to be symmtric about the origin.
</comment> </comment>
<constant name="BarrelTracking_length" value="SiliconTrackerOuterBarrelLength"/>
<constant name="BarrelTracking_rmax" value="SiliconTrackerOuterRadius"/>
<constant name="CentralTracking_rmax" value="SiliconTrackerOuterRadius"/> <constant name="CentralTracking_rmax" value="SiliconTrackerOuterRadius"/>
<constant name="CentralTracking_length" value="SiliconTrackerOuterBarrelLength + ForwardTrackingGEMLength"/> <constant name="CentralTracking_length" value="BarrelTracking_length + ForwardTrackingGEMLength"/>
<constant name="VertexTrackingRegion_length" value="SiliconTrackerOuterBarrelLength"/> <constant name="VertexTrackingRegion_length" value="SiliconTrackerOuterBarrelLength"/>
<comment> These are used by ddsim </comment> <comment> These are used by ddsim </comment>
......
<lccdd> <lccdd>
<comment> Central Barrel Tracker Silicon </comment> <comment> Endcap Tracker </comment>
<define> <define>
<comment> Si layer opiton </comment>
<constant name="GEMTrackerEndcapFoilX1" value="43.0 * mm"/> <constant name="GEMTrackerEndcapFoilX1" value="43.0 * mm"/>
<constant name="GEMTrackerEndcapFoilY" value="1020.0 * mm"/> <constant name="GEMTrackerEndcapFoilY" value="1020.0 * mm"/>
<constant name="GEMTrackerEndcapFoilOpeningAngle" value="30.1*degree"/> <constant name="GEMTrackerEndcapFoilOpeningAngle" value="30.1*degree"/>
......
<lccdd>
<comment>Micromegas tracker barrel</comment>
<define>
<constant name="MMTrackerBarrelLayer1_rmin" value="800.0 * mm"/>
<constant name="MMTrackerBarrelLayer1_length" value="500.0 * mm"/>
<constant name="MMTrackerBarrelLayer1_thickness" value="10.0 * mm"/>
<constant name="MMTrackerBarrel_NZModules" value="floor(BarrelTracking_length/MMTrackerBarrelLayer1_length)"/>
<constant name="MMTrackerBarrelModulesTotal_length" value="MMTrackerBarrel_NZModules*MMTrackerBarrelLayer1_length"/>
</define>
<limits>
</limits>
<regions>
</regions>
<display>
</display>
<detectors>
<detector id="MMTrackerBarrel_ID" name="MMTrackerBarrel" type="refdet_MMTrackerBarrel" readout="MMTrackerBarrelHits">
<module name="Module1" vis="Argonne_Gold">
<module_envelope
rmin="MMTrackerBarrelLayer1_rmin"
length="MMTrackerBarrelLayer1_length"
thickness="MMTrackerBarrelLayer1_thickness" phi="90*degree" />
<module_component thickness="1.0*mm" material="PEEK" sensitive="false">
<position x="0" />
</module_component>
<module_component thickness="1.0*mm" material="PEEK" sensitive="false"
length="MMTrackerBarrelLayer1_length-10.0*mm"
phi="89.0*degree" >
<position x="0" />
</module_component>
</module>
<layer module="Module1" id="1" vis="GreenVis">
<barrel_envelope
inner_r="MMTrackerBarrelLayer1_rmin-20.0*mm"
outer_r="MMTrackerBarrelLayer1_rmin + 20.0*mm"
z_length="MMTrackerBarrelModulesTotal_length" />
<comment>
phi0 : Starting phi of first module.
phi_tilt : Phi tilt of a module.
rc : Radius of the module center.
nphi : Number of modules in phi.
rphi_dr : The delta radius of every other module.
z0 : Z position of first module in phi.
nz : Number of modules to place in z.
dr : Radial displacement parameter, of every other module.
</comment>
<rphi_layout phi_tilt="0.0" nphi="4" phi0="0." rc="MMTrackerBarrelLayer1_rmin" dr="0.0 * mm"/>
<z_layout dr="0.0 * mm" z0="-MMTrackerBarrelModulesTotal_length/2.0 + MMTrackerBarrelLayer1_length/2.0"
nz="MMTrackerBarrel_NZModules"/>
</layer>
</detector>
</detectors>
<readouts>
<readout name="MMTrackerBarrelHits">
<segmentation type="CartesianGridXY" grid_size_x="1.0*mm" grid_size_y="1.0*mm" />
<id>system:8,sector:8,module:14,x:32:-16,y:-16</id>
</readout>
</readouts>
<plugins>
</plugins>
<fields>
</fields>
</lccdd>
...@@ -118,7 +118,6 @@ ...@@ -118,7 +118,6 @@
<include ref="compact/solenoid.xml"/> <include ref="compact/solenoid.xml"/>
<include ref="compact/ecal.xml"/> <include ref="compact/ecal.xml"/>
<include ref="compact/far_forward_detectors.xml"/> <include ref="compact/far_forward_detectors.xml"/>
<include ref="compact/cb_CTD_Si.xml"/>
<include ref="compact/ce_mrich.xml"/> <include ref="compact/ce_mrich.xml"/>
<include ref="compact/ce_GEM.xml"/> <include ref="compact/ce_GEM.xml"/>
<include ref="compact/hcal.xml"/> <include ref="compact/hcal.xml"/>
...@@ -128,8 +127,10 @@ ...@@ -128,8 +127,10 @@
<include ref="compact/forward_offM_tracker.xml"/> <include ref="compact/forward_offM_tracker.xml"/>
<include ref="compact/vertex_tracker.xml"/> <include ref="compact/vertex_tracker.xml"/>
<include ref="compact/gem_tracker_endcap.xml"/> <include ref="compact/gem_tracker_endcap.xml"/>
<include ref="compact/mm_tracker_barrel.xml"/>
<!-- <!--
<include ref="compact/ci_GEM.xml"/> <include ref="compact/ci_GEM.xml"/>
<include ref="compact/cb_CTD_Si.xml"/>
<include ref="compact/cb_VTX_Barrel.xml"/> <include ref="compact/cb_VTX_Barrel.xml"/>
<include ref="compact/ci_HCAL.xml"/> <include ref="compact/ci_HCAL.xml"/>
<include ref="compact/forward_rich.xml"/> <include ref="compact/forward_rich.xml"/>
......
//==========================================================================
// Specialized generic detector constructor
//==========================================================================
#include "Acts/Plugins/DD4hep/ActsExtension.hpp"
#include "Acts/Plugins/DD4hep/ConvertDD4hepMaterial.hpp"
#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/Printout.h"
using namespace std;
using namespace dd4hep;
using namespace dd4hep::detail;
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
typedef vector<PlacedVolume> Placements;
xml_det_t x_det = e;
Material air = description.air();
int det_id = x_det.id();
string det_name = x_det.nameStr();
DetElement sdet(det_name, det_id);
Acts::ActsExtension* barrelExtension = new Acts::ActsExtension();
barrelExtension->addType("barrel", "detector");
sdet.addExtension<Acts::ActsExtension>(barrelExtension);
Assembly assembly(det_name);
map<string, Volume> mod_volumes;
map<string, Placements> sensitives;
PlacedVolume pv;
sens.setType("tracker");
int n_modules = 0;
for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) {
n_modules++;
xml_comp_t x_mod = mi;
xml_comp_t m_env = x_mod.child(_U(module_envelope));
string m_nam = x_mod.nameStr();
Assembly module_assembly(_toString(n_modules, "mod_assembly_%d"));
auto module_rmin = m_env.rmin();
auto module_thickness = m_env.thickness();
auto module_length = m_env.length();
auto module_phi = getAttrOrDefault(m_env, _Unicode(phi), 90.0);
Volume m_vol(m_nam, Tube(module_rmin , module_rmin + module_thickness, module_length/ 2 ), air);
int ncomponents = 0, sensor_number = 1;
module_assembly.placeVolume(m_vol,Position(-module_rmin,0,0));
mod_volumes[m_nam] = module_assembly;
m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
auto comp_rmin = module_rmin;
for (xml_coll_t ci(x_mod, _U(module_component)); ci; ++ci, ++ncomponents) {
xml_comp_t x_comp = ci;
xml_comp_t x_pos = x_comp.position(false);
xml_comp_t x_rot = x_comp.rotation(false);
string c_nam = _toString(ncomponents, "component%d");
auto comp_thickness = x_comp.thickness();
comp_rmin = getAttrOrDefault(x_comp, _Unicode(rmin), comp_rmin);
auto comp_phi = getAttrOrDefault(x_comp, _Unicode(phi), module_phi);
auto comp_phi0 = getAttrOrDefault(x_comp, _Unicode(phi0), 0.0);
auto comp_length = getAttrOrDefault(x_comp, _Unicode(length), module_length);
Tube c_tube(comp_rmin, comp_rmin + comp_thickness, comp_length / 2 , -comp_phi/2.0+comp_phi0,comp_phi/2.0+comp_phi0);
Volume c_vol(c_nam, c_tube, description.material(x_comp.materialStr()));
PlacedVolume c_pv;
if (x_pos && x_rot) {
Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0));
RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0));
c_pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos));
} else if (x_rot) {
c_pv = m_vol.placeVolume(c_vol, RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)));
} else if (x_pos) {
c_pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)));
} else {
c_pv = m_vol.placeVolume(c_vol);
}
c_vol.setRegion(description, x_comp.regionStr());
c_vol.setLimitSet(description, x_comp.limitsStr());
c_vol.setVisAttributes(description, x_comp.visStr());
if (x_comp.isSensitive()) {
c_pv.addPhysVolID(_U(sensor), sensor_number++);
c_vol.setSensitiveDetector(sens);
sensitives[m_nam].push_back(c_pv);
}
comp_rmin = comp_rmin + comp_thickness;
}
}
for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
xml_comp_t x_layer = li;
xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
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();
string m_nam = x_layer.moduleStr();
string lay_nam = _toString(x_layer.id(), "layer%d");
Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2);
Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume.
lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
double phi0 = x_layout.phi0(); // Starting phi of first module.
double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module.
double rc = x_layout.rc(); // Radius of the module center.
int nphi = x_layout.nphi(); // Number of modules in phi.
double rphi_dr = x_layout.dr(); // The delta radius of every other module.
double phi_incr = (M_PI * 2) / nphi; // Phi increment for one module.
double phic = phi0; // Phi of the module center.
double z0 = z_layout.z0(); // Z position of first module in phi.
double nz = z_layout.nz(); // Number of modules to place in z.
double z_dr = z_layout.dr(); // Radial displacement parameter, of every other module.
Volume m_env = mod_volumes[m_nam];
DetElement lay_elt(sdet, _toString(x_layer.id(), "layer%d"), lay_id);
Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
layerExtension->addType("sensitive cylinder", "layer");
//layerExtension->addValue(10. * Acts::UnitConstants::mm, "r", "envelope");
lay_elt.addExtension<Acts::ActsExtension>(layerExtension);
Placements& sensVols = sensitives[m_nam];
// Z increment for module placement along Z axis.
// Adjust for z0 at center of module rather than
// the end of cylindrical envelope.
double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
// Starting z for module placement along Z axis.
double module_z = -z0;
int module = 1;
// Loop over the number of modules in phi.
for (int ii = 0; ii < nphi; ii++) {
double dx = z_dr * std::cos(phic + phi_tilt); // Delta x of module position.
double dy = z_dr * std::sin(phic + phi_tilt); // Delta y of module position.
double x = rc * std::cos(phic); // Basic x module position.
double y = rc * std::sin(phic); // Basic y module position.
// Loop over the number of modules in z.
for (int j = 0; j < nz; j++) {
string module_name = _toString(module, "module%d");
DetElement mod_elt(lay_elt, module_name, module);
// Module PhysicalVolume.
// Transform3D
// tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z));
// NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the
// outside
Transform3D tr(RotationZYX(phic - phi_tilt,0, 0), Position(x, y, module_z));
pv = lay_vol.placeVolume(m_env, tr);
pv.addPhysVolID("module", module);
mod_elt.setPlacement(pv);
for (size_t ic = 0; ic < sensVols.size(); ++ic) {
PlacedVolume sens_pv = sensVols[ic];
DetElement comp_elt(mod_elt, sens_pv.volume().name(), module);
comp_elt.setPlacement(sens_pv);
Acts::ActsExtension* moduleExtension = new Acts::ActsExtension("YZX");
comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
}
/// Increase counters etc.
module++;
// Adjust the x and y coordinates of the module.
x += dx;
y += dy;
// Flip sign of x and y adjustments.
dx *= -1;
dy *= -1;
// Add z increment to get next z placement pos.
module_z += z_incr;
}
phic += phi_incr; // Increment the phi placement of module.
rc += rphi_dr; // Increment the center radius according to dr parameter.
rphi_dr *= -1; // Flip sign of dr parameter.
module_z = -z0; // Reset the Z placement parameter for module.
}
// Create the PhysicalVolume for the layer.
pv = assembly.placeVolume(lay_vol); // Place layer in mother
pv.addPhysVolID("layer", lay_id); // Set the layer ID.
lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
lay_elt.setPlacement(pv);
}
sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
assembly.setVisAttributes(description.invisible());
pv = description.pickMotherVolume(sdet).placeVolume(assembly);
pv.addPhysVolID("system", det_id); // Set the subdetector system ID.
pv.addPhysVolID("barrel", 1); // Flag this as a barrel subdetector.
sdet.setPlacement(pv);
return sdet;
}
// clang-format off
DECLARE_DETELEMENT(refdet_CylinderTrackerBarrel, create_detector)
DECLARE_DETELEMENT(refdet_MMTrackerBarrel, create_detector)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment