DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
ForwardDetector_geo.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 //
14 // Specialized generic detector constructor
15 //
16 //==========================================================================
17 #include "XML/Layering.h"
19 
20 using namespace std;
21 using namespace dd4hep;
22 using namespace dd4hep::detail;
23 
24 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
25  xml_det_t x_det = e;
26  xml_dim_t dim = x_det.dimensions();
27  bool reflect = x_det.reflect();
28  xml_comp_t beam = x_det.beampipe();
29  string det_name = x_det.nameStr();
30  int id = x_det.id();
31  Material air = description.air();
32  DetElement sdet (det_name,id);
33  Layering layering (x_det);
34 
35  Volume motherVol = description.pickMotherVolume(sdet);
36 
37  double rmax = dim.outer_r();
38  double rmin = dim.inner_r();
39  double zinner = dim.inner_z();
40  double outgoingR = beam.outgoing_r();
41  double incomingR = beam.incoming_r();
42  double xangle = beam.crossing_angle();
43  double xangleHalf = xangle/2;
44  double thickness = layering.totalThickness();
45  double zpos = zinner + thickness/2;
46  // Beampipe position in envelope.
47  double beamPosX = std::tan(xangleHalf) * zpos;
48 
49  // Detector envelope solid.
50  Tube envelopeTube(rmin,rmax,thickness/2);
51 
52  // First envelope bool subtracion of outgoing beampipe.
53  // Incoming beampipe solid.
54  Tube beamInTube(0,outgoingR,thickness);
55  // Position of incoming beampipe.
56  Position beamInPos(beamPosX,0,0);
58  Rotation3D beamInRot(RotationY(1.*xangleHalf));
59  Transform3D beamInTrans(beamInRot,beamInPos);
60 
61  // Second envelope bool subtracion of outgoing beampipe.
62  // Outgoing beampipe solid.
63  Tube beamOutTube(0,incomingR,thickness);
64  // Position of outgoing beampipe.
65  Position beamOutPos(-beamPosX,0,0);
66  // Rotation of outgoing beampipe.
67  Rotation3D beamOutRot(RotationY(-xangleHalf));
68  Transform3D beamOutTrans(beamOutRot,beamOutPos);
69 
70  // First envelope bool subtraction of incoming beampipe.
71  SubtractionSolid envelopeSubtraction1(envelopeTube,beamInTube,beamInTrans);
72  SubtractionSolid envelopeSubtraction2(envelopeSubtraction1,beamOutTube,beamOutTrans);
73 
74  // Final envelope bool volume.
75  Volume envelopeVol(det_name+"_envelope", envelopeSubtraction2, air);
76 
77  // Process each layer element.
78  double layerPosZ = -thickness / 2;
79  double layerDisplZ = 0;
80 
81  int layerCount = 1;
82  for(xml_coll_t c(x_det,_U(layer)); c; ++c) {
83  xml_comp_t x_layer = c;
84  double layerThickness = layering.singleLayerThickness(x_layer);
85 
86  // Create tube envelope for this layer, which can be reused in bool definition
87  // in the repeat loop below.
88  Tube layerTube(rmin,rmax,layerThickness * 0.5);
89 
90  for(int i=0, repeat=x_layer.repeat(); i<repeat; ++i) {
91  string layer_nam = _toString(layerCount,"layer%d");
92  // Increment to new layer position.
93  layerDisplZ += layerThickness / 2;
94  layerPosZ += layerThickness / 2;
95 
96  // First layer subtraction solid.
97  DetElement layer(sdet,layer_nam,sdet.id());
98  double layerGlobalZ = zinner + layerDisplZ;
99  double layerPosX = std::tan(xangleHalf) * layerGlobalZ;
100  Position layer1SubPos( layerPosX,0,0);
101  Position layer2SubPos(-layerPosX,0,0);
102 
103  SubtractionSolid layerSubtraction1(layerTube,beamInTube,Transform3D(beamInRot,layer1SubPos));
104  // Second layer subtraction solid.
105  SubtractionSolid layerSubtraction2(layerSubtraction1,beamOutTube,Transform3D(beamOutRot,layer2SubPos));
106  // Layer LV.
107  Volume layerVol(det_name+"_"+layer_nam,layerSubtraction2,air);
108 
109  // Slice loop.
110  int sliceCount = 1;
111  double slicePosZ = -layerThickness / 2;
112  double sliceDisplZ = 0;
113  for(xml_coll_t l(x_layer,_U(slice)); l; ++l) {
114  xml_comp_t x_slice = l;
115  string slice_nam = _toString(sliceCount,"slice%d");
117  double sliceThickness = x_slice.thickness();
118  Material slice_mat = description.material(x_slice.materialStr());
119 
120  // Go to mid of this slice.
121  sliceDisplZ += sliceThickness / 2;
122  slicePosZ += sliceThickness / 2;
123 
124  // Slice's basic tube.
125  Tube sliceTube(rmin,rmax,sliceThickness * 0.5);
126  DetElement slice(layer,slice_nam,sdet.id());
127  double sliceGlobalZ = zinner + (layerDisplZ - layerThickness / 2) + sliceDisplZ;
128  double slicePosX = std::tan(xangleHalf) * sliceGlobalZ;
129 
130  // First slice subtraction solid.
131  SubtractionSolid sliceSubtraction1(sliceTube,beamInTube,Transform3D(beamInRot,Position(slicePosX,0,0)));
132  // Second slice subtraction solid.
133  SubtractionSolid sliceSubtraction2(sliceSubtraction1,beamOutTube,Transform3D(beamOutRot,Position(-slicePosX,0,0)));
134  // Slice LV.
135  Volume sliceVol(det_name+"_"+layer_nam+"_"+slice_nam, sliceSubtraction2, slice_mat);
136 
137  if ( x_slice.isSensitive() ) {
138  sens.setType("calorimeter");
139  sliceVol.setSensitiveDetector(sens);
140  }
141  // Set attributes of slice
142  slice.setAttributes(description, sliceVol, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
143 
144  // Place volume in layer
145  PlacedVolume pv = layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ));
146  pv.addPhysVolID("slice",sliceCount);
147  slice.setPlacement(pv);
148 
149  // Start of next slice.
150  sliceDisplZ += sliceThickness / 2;
151  slicePosZ += sliceThickness / 2;
152  ++sliceCount;
153  }
154  // Set attributes of slice
155  layer.setAttributes(description, layerVol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
156 
157  // Layer PV.
158  PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ));
159  layerPV.addPhysVolID("layer", layerCount);
160  layer.setPlacement(layerPV);
161 
162  // Increment to start of next layer.
163  layerDisplZ += layerThickness / 2;
164  layerPosZ += layerThickness / 2;
165  ++layerCount;
166  }
167  }
168  sdet.setVisAttributes(description, x_det.visStr(), envelopeVol);
169 
170  // Reflect it.
171  if ( reflect ) {
172  Assembly assembly(det_name+"_assembly");
173  PlacedVolume pv = motherVol.placeVolume(assembly);
174  pv.addPhysVolID("system", id);
175  sdet.setPlacement(pv);
176 
177  DetElement sdetA(sdet,det_name+"_A",x_det.id());
178  pv = assembly.placeVolume(envelopeVol,Transform3D(RotationZ(M_PI),Position(0,0,zpos)));
179  pv.addPhysVolID("barrel", 1);
180  sdetA.setPlacement(pv);
181 
182  DetElement sdetB = sdetA.clone(det_name+"_B",x_det.id());
183  sdet.add(sdetB);
184  pv = assembly.placeVolume(envelopeVol,Transform3D(RotationY(M_PI),Position(0,0,-zpos)));
185  pv.addPhysVolID("barrel", 2);
186  sdetB.setPlacement(pv);
187  }
188  else {
189  PlacedVolume pv = motherVol.placeVolume(envelopeVol,Transform3D(RotationZ(M_PI),Position(0,0,zpos)));
190  pv.addPhysVolID("system", id);
191  pv.addPhysVolID("barrel", 1);
192  sdet.setPlacement(pv);
193  }
194  return sdet;
195 }
196 
197 DECLARE_DETELEMENT(DD4hep_ForwardDetector,create_detector)
198 
dd4hep::xml::Collection_t
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:636
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:44
DECLARE_DETELEMENT
#define DECLARE_DETELEMENT(name, func)
Definition: Factories.h:339
M_PI
#define M_PI
Definition: Handle.h:33
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
dd4hep::DetElement::clone
DetElement clone(int flag) const
Clone (Deep copy) the DetElement structure.
Definition: DetElement.cpp:274
dd4hep::PlacedVolume::addPhysVolID
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
Definition: Volumes.cpp:485
dd4hep::Handle< NamedObject >
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::Rotation3D
ROOT::Math::Rotation3D Rotation3D
Definition: Objects.h:113
dd4hep::Detector::pickMotherVolume
virtual Volume pickMotherVolume(const DetElement &sd) const =0
Access mother volume by detector element.
dd4hep::DetElement::add
DetElement & add(DetElement sub_element)
Add new child to the detector structure.
Definition: DetElement.cpp:258
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
dd4hep::Assembly
Implementation class extending the ROOT assembly volumes (TGeoVolumeAssembly)
Definition: Volumes.h:762
dd4hep::Volume::placeVolume
PlacedVolume placeVolume(const Volume &volume) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:830
xml_comp_t
dd4hep::xml::Component xml_comp_t
Definition: XML.h:33
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:272
dd4hep::Detector::material
virtual Material material(const std::string &name) const =0
Retrieve a matrial by its name from the detector description.
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::Detector::air
virtual Material air() const =0
Return handle to material describing air.
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:378
dd4hep::detail
DD4hep internal namespace.
Definition: Alignments.h:32
dd4hep::RotationZ
ROOT::Math::RotationZ RotationZ
Definition: Objects.h:107
xml_det_t
dd4hep::xml::DetElement xml_det_t
Definition: XML.h:32
_U
#define _U(a)
Definition: Tags.h:23
Layering.h
dd4hep::DetElement::setPlacement
DetElement & setPlacement(const PlacedVolume &volume)
Set the physical volumes of the detector element.
Definition: DetElement.cpp:330
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:117
dd4hep::Layering
Class to convert a layering object from the compact notation.
Definition: Layering.h:116
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:81
dd4hep::RotationY
ROOT::Math::RotationY RotationY
Definition: Objects.h:109
DetFactoryHelper.h
std
Definition: Plugins.h:30
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::Tube
Class describing a tube shape of a section of a tube.
Definition: Shapes.h:628
xml_dim_t
dd4hep::xml::Dimension xml_dim_t
Definition: XML.h:31
dd4hep::SubtractionSolid
Class describing boolean subtraction solid.
Definition: Shapes.h:1878
dd4hep::SensitiveDetector::setType
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:403