1 package org.lcsim.geometry.compact.converter.lcdd;
2
3 import org.jdom.Element;
4 import org.jdom.JDOMException;
5 import org.lcsim.geometry.compact.converter.lcdd.util.Cone;
6 import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
7 import org.lcsim.geometry.compact.converter.lcdd.util.Material;
8 import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
9 import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
10 import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
11 import org.lcsim.geometry.compact.converter.lcdd.util.Solids;
12 import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
13 import org.lcsim.geometry.compact.converter.lcdd.util.Tube;
14 import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
15 import org.lcsim.geometry.layer.LayerSlice;
16 import org.lcsim.geometry.layer.LayerStack;
17 import org.lcsim.geometry.layer.Layering;
18
19 public class CylindricalEndcapCalorimeter2 extends LCDDSubdetector
20 {
21 CylindricalEndcapCalorimeter2(Element c) throws JDOMException
22 {
23 super(c);
24 }
25
26 void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
27 {
28
29 int id = node.getAttribute("id").getIntValue();
30 String subdetectorName = node.getAttributeValue("name");
31
32
33 Material air = lcdd.getMaterial("Air");
34 Solids solids = lcdd.getSolids();
35 Structure structure = lcdd.getStructure();
36 Volume motherVolume = lcdd.pickMotherVolume(this);
37
38
39 Element dimensions = node.getChild("dimensions");
40 double zmin = dimensions.getAttribute("zmin").getDoubleValue();
41 double rmin = dimensions.getAttribute("rmin").getDoubleValue();
42 double rmax = dimensions.getAttribute("rmax").getDoubleValue();
43 double innerAngle = dimensions.getAttribute("angle").getDoubleValue();
44
45
46 LayerStack layers = Layering.makeLayering(this.node).getLayerStack();
47
48
49 double thickness = layers.getTotalThickness();
50
51
52 double rmin2 = rmin + (thickness * Math.tan(innerAngle));
53
54
55
56 Cone envelopeCone = new Cone(subdetectorName + "_envelope_cone", rmin, rmin2, rmax, rmax, thickness);
57 solids.addSolid(envelopeCone);
58
59
60 Volume envelopeVolume = new Volume(subdetectorName + "_volume", envelopeCone, air);
61
62
63 double layerZ = -thickness / 2;
64
65
66 double layerRmin = rmin;
67
68
69 for (int i = 0, l = layers.getNumberOfLayers(); i < l; i++)
70 {
71
72 double layerThickness = layers.getLayer(i).getThickness();
73
74
75 double layerdx = Math.tan(innerAngle) * layerThickness;
76
77
78 layerRmin += layerdx;
79
80
81
82 Tube layerTube = new Tube(subdetectorName + "_layer" + i + "_tube", layerRmin, rmax, layerThickness / 2);
83 solids.addSolid(layerTube);
84
85
86 Volume layerVolume = new Volume(subdetectorName + "_layer" + i + "_volume", layerTube, air);
87
88
89 double sliceZ = -layerThickness / 2;
90 int sliceCount = 0;
91 for (LayerSlice slice : layers.getLayer(i).getSlices())
92 {
93
94 double sliceThickness = slice.getThickness();
95
96
97 Tube sliceTube =
98 new Tube(subdetectorName + "_layer" + i + "_slice" + sliceCount + "_tube", layerRmin, rmax, sliceThickness / 2);
99 solids.addSolid(sliceTube);
100
101
102 Volume sliceVolume = new Volume(subdetectorName + "_layer" + i + "_slice" + sliceCount + "_volume", sliceTube, lcdd.getMaterial(slice.getMaterial().getName()));
103 structure.addVolume(sliceVolume);
104
105
106 if (slice.isSensitive())
107 sliceVolume.setSensitiveDetector(sens);
108
109
110 PhysVol slicePhysVol = new PhysVol(sliceVolume);
111 slicePhysVol.setZ(sliceZ + sliceThickness / 2);
112 slicePhysVol.addPhysVolID("slice", sliceCount);
113 layerVolume.addPhysVol(slicePhysVol);
114
115
116 sliceZ += sliceThickness;
117
118
119 ++sliceCount;
120 }
121
122
123 structure.addVolume(layerVolume);
124
125
126 PhysVol layerPhysVol = new PhysVol(layerVolume);
127 layerPhysVol.addPhysVolID("layer", i);
128 layerPhysVol.setZ(layerZ + layerThickness / 2);
129 envelopeVolume.addPhysVol(layerPhysVol);
130
131
132 layerZ += layerThickness;
133 }
134
135
136 structure.addVolume(envelopeVolume);
137
138
139 PhysVol endcapPositivePhysVol = new PhysVol(envelopeVolume);
140 endcapPositivePhysVol.addPhysVolID("system", id);
141 endcapPositivePhysVol.addPhysVolID("barrel", 1);
142 endcapPositivePhysVol.setZ(zmin + thickness / 2);
143 motherVolume.addPhysVol(endcapPositivePhysVol);
144
145
146 PhysVol endcapNegativePhysVol = new PhysVol(envelopeVolume);
147 endcapNegativePhysVol.addPhysVolID("system", id);
148 endcapNegativePhysVol.addPhysVolID("barrel", 2);
149 endcapNegativePhysVol.setZ(-zmin - thickness / 2);
150 Rotation negativeEndcapRotation = new Rotation(subdetectorName + "_negative_rotation");
151 lcdd.getDefine().addRotation(negativeEndcapRotation);
152 negativeEndcapRotation.setX(Math.PI);
153 endcapNegativePhysVol.setRotation(negativeEndcapRotation);
154 motherVolume.addPhysVol(endcapNegativePhysVol);
155 }
156
157 public boolean isCalorimeter()
158 {
159 return true;
160 }
161 }