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 SiTrackerSpectrometer 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 SiTrackerSpectrometer(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          boolean flipSA=false;
47          if ( node.getAttribute( "flipSA" ) != null )
48          {
49                  flipSA = node.getAttribute( "flipSA" ).getBooleanValue();
50          }
51          for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
52              Element module = (Element) i.next();
53              String moduleName = module.getAttributeValue("name");
54              moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
55              modules.put(moduleName, makeModule(moduleParameters.get(moduleName), sd, lcdd));
56          }
57  
58          for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
59              Element layerElement = (Element) i.next();
60              int layerId = layerElement.getAttribute("id").getIntValue();
61              int ringCount = 0;
62              int moduleNumber = 0;
63              for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
64                  Element ringElement = (Element) j.next();
65                  double zLayer = ringElement.getAttribute("z").getDoubleValue();
66                  double dz = ringElement.getAttribute("dz").getDoubleValue();
67                  double xStart = ringElement.getAttribute("xStart").getDoubleValue();
68                   double xStep = ringElement.getAttribute("xStep").getDoubleValue();
69                  int nx = ringElement.getAttribute("nx").getIntValue();
70                  double yStart = ringElement.getAttribute("yStart").getDoubleValue();
71                  int ny = ringElement.getAttribute("ny").getIntValue();
72                  double yStep = ringElement.getAttribute("yStep").getDoubleValue();
73                  double phi0 = 0;
74                  if (ringElement.getAttribute("phi0") != null) {
75                      phi0 = ringElement.getAttribute("phi0").getDoubleValue();
76                  }
77                  String module = ringElement.getAttributeValue("module");
78  
79                  Volume moduleVolume = modules.get(module);
80                  if (moduleVolume == null) {
81                      throw new RuntimeException("Module " + module + " was not found.");
82                  }
83  
84               
85                  double x, y, z;
86                  z = zLayer;
87                  x = xStart;
88  
89                  for (int k = 0; k < nx; k++) {
90                      y = yStart;
91                      for (int kk = 0; kk < ny; kk++) {
92                          String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
93  
94                          Position p = new Position(moduleBaseName + "_position");
95  
96                          p.setX(x );
97                          p.setY(y);
98                          p.setZ(z+ dz);
99                          Rotation rot = new Rotation(moduleBaseName + "_rotation");
100                         rot.setX(-Math.PI / 2);
101                         rot.setY(Math.PI / 2+phi0);
102                         rot.setZ(0);
103                         
104                        
105                         lcdd.add(p);
106                         lcdd.add(rot);
107 
108                         PhysVol pv = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), p, rot);
109                         pv.addPhysVolID("system", sysId);
110 
111                         pv.addPhysVolID("barrel", 0);
112                         pv.addPhysVolID("layer", layerId);
113                         pv.addPhysVolID("module", moduleNumber);
114                          ++moduleNumber;
115                         if (reflect) {
116                             Position pr = new Position(moduleBaseName + "_reflect_position");
117                             pr.setX(x);
118                             pr.setY(-y);
119                             pr.setZ(z + dz);
120                             Rotation rotr = new Rotation(moduleBaseName + "_reflect_rotation");
121                             double rphi0=phi0;
122                             if(flipSA) rphi0=-rphi0;
123                             rotr.setX(-Math.PI / 2);
124                             rotr.setY(Math.PI / 2+rphi0);
125                             rotr.setZ(0);
126 
127                             lcdd.add(pr);
128                             lcdd.add(rotr);
129                             System.out.println("Reflecting "+ x+"  "+y+"  "+z);
130                             PhysVol pvr = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), pr, rotr);
131                             pvr.addPhysVolID("system", sysId);
132                             pvr.addPhysVolID("barrel", 0);
133                             pvr.addPhysVolID("layer", layerId);
134                             pvr.addPhysVolID("module", moduleNumber);
135                            
136                         }
137                         dz = -dz;
138                         y += yStep;
139                         ++moduleNumber;
140                     }
141                     x += xStep;
142                 }
143             }
144         }
145     }
146 
147     private Volume makeModule(SiTrackerModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
148         double thickness = params.getThickness();
149         double dx1, dx2, dy1, dy2, dz;
150         dy1 = dy2 = thickness / 2;
151         dx1 = params.getDimension(0);
152         dx2 = params.getDimension(1);
153         dz = params.getDimension(2);
154         Trapezoid envelope = new Trapezoid(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
155         lcdd.add(envelope);
156         Volume volume = new Volume(params.getName() + "Volume", envelope, vacuum);
157         makeModuleComponents(volume, params, sd, lcdd);
158         if (params.getVis() != null) {
159             volume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
160         }
161         lcdd.add(volume);
162         return volume;
163     }
164 
165     private void makeModuleComponents(Volume moduleVolume, SiTrackerModuleParameters moduleParameters, SensitiveDetector sd, LCDD lcdd) {
166         Trapezoid trd = (Trapezoid) lcdd.getSolid(moduleVolume.getSolidRef());
167 
168         double x1 = trd.x1();
169         double x2 = trd.x2();
170         double y1 = trd.y1();
171         double z = trd.z();
172 
173         double posY = -y1;
174 
175         String moduleName = moduleVolume.getVolumeName();
176 
177         int sensor = 0;
178         for (SiTrackerModuleComponentParameters component : moduleParameters) {
179             double thickness = component.getThickness();
180 
181             Material material = null;
182             try {
183                 material = lcdd.getMaterial(component.getMaterialName());
184             } catch (JDOMException x) {
185                 throw new RuntimeException(x);
186             }
187             boolean sensitive = component.isSensitive();
188             int componentNumber = component.getComponentNumber();
189 
190             posY += thickness / 2;
191 
192             String componentName = moduleName + "_component" + componentNumber;
193 
194             Trapezoid sliceTrd = new Trapezoid(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
195             lcdd.add(sliceTrd);
196 
197             Volume volume = new Volume(componentName, sliceTrd, material);
198             lcdd.add(volume);
199 
200             Position position = new Position(componentName + "_position", 0., posY, 0);
201             lcdd.add(position);
202             Rotation rotation = new Rotation(componentName + "_rotation");
203             lcdd.add(rotation);
204 
205             PhysVol pv = new PhysVol(volume, moduleVolume, position, rotation);
206             pv.addPhysVolID("component", componentNumber);
207 
208             if (sensitive) {
209                 if (sensor > 1) {
210                     throw new RuntimeException("Maximum of 2 sensors per module.");
211                 }
212                 pv.addPhysVolID("sensor", sensor);
213                 volume.setSensitiveDetector(sd);
214                 ++sensor;
215             }
216 
217             if (component.getVis() != null) {
218                 volume.setVisAttributes(lcdd.getVisAttributes(component.getVis()));
219             }
220 
221             posY += thickness / 2;
222         }
223     }
224 
225     public boolean isTracker() {
226         return true;
227     }
228 }