1 package org.lcsim.geometry.compact.converter.lcdd;
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5 import java.util.Map;
6
7 import org.jdom.Element;
8 import org.jdom.JDOMException;
9 import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
10 import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
11 import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
12 import org.lcsim.geometry.compact.converter.lcdd.util.Material;
13 import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
14 import org.lcsim.geometry.compact.converter.lcdd.util.Position;
15 import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
16 import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
17 import org.lcsim.geometry.compact.converter.lcdd.util.Trapezoid;
18 import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
19
20
21
22
23
24
25
26 public class SiTrackerFixedTarget extends LCDDSubdetector {
27
28 Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
29 Map<String, Volume> modules = new HashMap<String, Volume>();
30 Material vacuum;
31
32 public SiTrackerFixedTarget(Element node) throws JDOMException {
33 super(node);
34 }
35
36 void addToLCDD(LCDD lcdd, SensitiveDetector sd) throws JDOMException {
37 int sysId = node.getAttribute("id").getIntValue();
38 String subdetName = node.getAttributeValue("name");
39 vacuum = lcdd.getMaterial("Vacuum");
40
41
42
43
44
45
46 for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
47 Element module = (Element) i.next();
48 String moduleName = module.getAttributeValue("name");
49 moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
50 modules.put(moduleName, makeModule(moduleParameters.get(moduleName), sd, lcdd));
51 }
52
53 for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
54 Element layerElement = (Element) i.next();
55 int layerId = layerElement.getAttribute("id").getIntValue();
56 int ringCount = 0;
57 int moduleNumber = 0;
58 for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
59 Element ringElement = (Element) j.next();
60
61 double x = ringElement.getAttribute("x").getDoubleValue();
62 double y = ringElement.getAttribute("y").getDoubleValue();
63 double phi0 = 0;
64 if (ringElement.getAttribute("phi0") != null) {
65 phi0 = ringElement.getAttribute("phi0").getDoubleValue();
66 }
67 double zstart = ringElement.getAttribute("zstart").getDoubleValue();
68
69
70
71
72
73 String module = ringElement.getAttributeValue("module");
74 Volume moduleVolume = modules.get(module);
75 if (moduleVolume == null) {
76 throw new RuntimeException("Module " + module + " was not found.");
77 }
78
79 double phi = phi0;
80
81 String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
82
83
84
85
86 Position p = new Position(moduleBaseName + "_position");
87
88
89
90 p.setX(zstart);
91 p.setY(y);
92 p.setZ(x);
93 Rotation rot = new Rotation(moduleBaseName + "_rotation");
94
95 rot.setZ(-Math.PI / 2);
96
97
98 lcdd.add(p);
99 lcdd.add(rot);
100
101 PhysVol pv = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), p, rot);
102 pv.addPhysVolID("system", sysId);
103
104 pv.addPhysVolID("barrel", 0);
105 pv.addPhysVolID("layer", layerId);
106 pv.addPhysVolID("module", moduleNumber);
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 ++ringCount;
131 ++moduleNumber;
132
133 }
134 }
135 setCombineHits(node, sd);
136 }
137
138 private Volume makeModule(SiTrackerModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
139 double thickness = params.getThickness();
140 double dx1, dx2, dy1, dy2, dz;
141 dy1 = dy2 = thickness / 2;
142 dx1 = params.getDimension(0);
143 dx2 = params.getDimension(1);
144 dz = params.getDimension(2);
145 Trapezoid envelope = new Trapezoid(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
146 lcdd.add(envelope);
147 Volume volume = new Volume(params.getName() + "Volume", envelope, vacuum);
148 makeModuleComponents(volume, params, sd, lcdd);
149 if (params.getVis() != null) {
150 volume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
151 }
152 lcdd.add(volume);
153 return volume;
154 }
155
156 private void makeModuleComponents(Volume moduleVolume, SiTrackerModuleParameters moduleParameters, SensitiveDetector sd, LCDD lcdd) {
157 Trapezoid trd = (Trapezoid) lcdd.getSolid(moduleVolume.getSolidRef());
158
159 double x1 = trd.x1();
160 double x2 = trd.x2();
161 double y1 = trd.y1();
162 double z = trd.z();
163
164 double posY = -y1;
165
166 String moduleName = moduleVolume.getVolumeName();
167
168 int sensor = 0;
169 for (SiTrackerModuleComponentParameters component : moduleParameters) {
170 double thickness = component.getThickness();
171
172 Material material = null;
173 try {
174 material = lcdd.getMaterial(component.getMaterialName());
175 } catch (JDOMException x) {
176 throw new RuntimeException(x);
177 }
178 boolean sensitive = component.isSensitive();
179 int componentNumber = component.getComponentNumber();
180
181 posY += thickness / 2;
182
183 String componentName = moduleName + "_component" + componentNumber;
184
185 Trapezoid sliceTrd = new Trapezoid(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
186 lcdd.add(sliceTrd);
187
188 Volume volume = new Volume(componentName, sliceTrd, material);
189 lcdd.add(volume);
190
191 Position position = new Position(componentName + "_position", 0., posY, 0);
192 lcdd.add(position);
193 Rotation rotation = new Rotation(componentName + "_rotation");
194 lcdd.add(rotation);
195
196 PhysVol pv = new PhysVol(volume, moduleVolume, position, rotation);
197 pv.addPhysVolID("component", componentNumber);
198
199 if (sensitive) {
200 if (sensor > 1) {
201 throw new RuntimeException("Maximum of 2 sensors per module.");
202 }
203 pv.addPhysVolID("sensor", sensor);
204 volume.setSensitiveDetector(sd);
205 ++sensor;
206 }
207
208 if (component.getVis() != null) {
209 volume.setVisAttributes(lcdd.getVisAttributes(component.getVis()));
210 }
211
212 posY += thickness / 2;
213 }
214 }
215
216 public boolean isTracker() {
217 return true;
218 }
219 }