View Javadoc

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   * An LCDD converter for a Silicon endcap tracker model based on Bill Cooper's design from
22   * <a href="http://ilcagenda.linearcollider.org/materialDisplay.py?contribId=58&sessionId=1&materialId=slides&confId=2784">Boulder SiD Workshop 2008</a>.
23   * 
24   * @author jeremym 
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  //        boolean reflect;
41  //        if (node.getAttribute("reflect") != null)
42  //            reflect = node.getAttribute("reflect").getBooleanValue();
43  //        else
44  //            reflect = true;
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  //                double r = ringElement.getAttribute("r").getDoubleValue();
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  //                double dz = 0;
69  //                if (ringElement.getAttribute("dz") != null) {
70  //                    dz = Math.abs(ringElement.getAttribute("dz").getDoubleValue());
71  //                }
72  //                int nmodules = ringElement.getAttribute("nmodules").getIntValue();
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  //                double iphi = (2 * Math.PI) / nmodules;
79                  double phi = phi0;
80  //                for (int k = 0; k < nmodules; k++) {
81                  String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
82  
83  //                    double x = r * Math.cos(phi);
84  //                    double y = r * Math.sin(phi);
85  
86                  Position p = new Position(moduleBaseName + "_position");
87  //                p.setX(x);
88  //                p.setY(y);
89  //                p.setZ(zstart);
90                  p.setX(zstart);
91                  p.setY(y);
92                  p.setZ(x);
93                  Rotation rot = new Rotation(moduleBaseName + "_rotation");
94  //                rot.setX(-Math.PI / 2);
95                    rot.setZ(-Math.PI / 2);
96  //                rot.setY(-Math.PI / 2 - phi);
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 //                pv.addPhysVolID("barrel", 1); // positive endcap
104                         pv.addPhysVolID("barrel", 0); // positive endcap
105                 pv.addPhysVolID("layer", layerId);
106                 pv.addPhysVolID("module", moduleNumber);
107 
108 //                    if (reflect) {
109 //                        Position pr = new Position(moduleBaseName + "_reflect_position");
110 //                        pr.setX(x);
111 //                        pr.setY(y);
112 //                        pr.setZ(-zstart - dz);
113 //                        Rotation rotr = new Rotation(moduleBaseName + "_reflect_rotation");
114 //                        rotr.setX(-Math.PI / 2);
115 //                        rotr.setY(-Math.PI / 2 - phi);
116 //                        rotr.setZ(Math.PI);
117 
118 //                        lcdd.add(pr);
119 //                        lcdd.add(rotr);
120 
121 //                        PhysVol pvr = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), pr, rotr);
122 //                        pvr.addPhysVolID("system", sysId);
123 //                        pvr.addPhysVolID("barrel", 2);
124 //                        pvr.addPhysVolID("layer", layerId);
125 //                        pvr.addPhysVolID("module", moduleNumber);
126 //                    }
127 
128 //                    dz = -dz;
129 //                    phi += iphi;
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 }