View Javadoc

1   package org.lcsim.geometry.subdetector;
2   
3   import hep.graphics.heprep.HepRep;
4   import hep.graphics.heprep.HepRepFactory;
5   import hep.graphics.heprep.HepRepInstance;
6   import hep.graphics.heprep.HepRepInstanceTree;
7   import hep.graphics.heprep.HepRepType;
8   import hep.graphics.heprep.HepRepTypeTree;
9   import hep.physics.vec.BasicHep3Vector;
10  import hep.physics.vec.Hep3Vector;
11  
12  import org.jdom.Attribute;
13  import org.jdom.DataConversionException;
14  import org.jdom.Element;
15  import org.jdom.JDOMException;
16  import org.lcsim.detector.IRotation3D;
17  import org.lcsim.detector.ITransform3D;
18  import org.lcsim.detector.RotationPassiveXYZ;
19  import org.lcsim.detector.Transform3D;
20  import org.lcsim.detector.Translation3D;
21  
22  /**
23   * This class represents a test beam detector that can be positioned and rotated
24   * in global coordinates.  There are seperate, concrete implementations for calorimeters
25   * and trackers.
26   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
27   * @version $Id: AbstractTestBeam.java,v 1.13 2013/02/13 10:47:50 grefe Exp $
28   */
29  public abstract class AbstractTestBeam extends AbstractLayeredSubdetector {
30  
31      /* Envelope volume dimensions. */
32      double dimensionX;
33      double dimensionY;
34      double dimensionZ;
35      double radius;
36      
37      /* Default number of sides. */
38      int DEFAULT_NSIDES = 4;
39  
40      /* The position and rotation in global space. */
41      Hep3Vector position;    
42      IRotation3D rotation;
43      ITransform3D transform;
44  
45      /**
46       * The constructor taking an XML element.
47       * @param node The XML element for the detector in the compact description.
48       * @throws JDOMException If XML parsing fails.
49       */
50      public AbstractTestBeam(Element node) throws JDOMException {
51          super(node);
52          build(node);
53      }
54  
55      /**
56       * Build the detector from XML.
57       * @param node The XML node.
58       * @throws JDOMException if there is a problem parsing parameters.
59       */
60      private void build(Element node) throws JDOMException {
61          
62          /* Get settings for detector dimensions. */
63          Element dimensions = node.getChild("dimensions");
64  
65          /* Compute the dimensions of the detector. */
66          computeDimensions(dimensions);
67  
68          /* Compute the outer radius from the dimensions. */
69          radius = computeRadius();
70  
71          /* Set the Cartesian position of the test beam detector. */
72          setPosition(node);
73          
74          /* Set the rotation of the detector. */
75          setRotation(node);
76          
77          /* Set the transform combining rotation and position. */
78          setTransform();
79      }
80  
81      /**
82       * Set the transform combining the position and rotation.
83       */
84      private void setTransform() {
85          transform = new Transform3D(new Translation3D(position), rotation);
86      }
87  
88      /**
89       * Return the width in X.
90       * @return width in X
91       */
92      public double getDimensionX() {
93          return dimensionX;
94      }
95  
96      /**
97       * Return the width in Y.
98       * @return width in Y
99       */
100     public double getDimensionY() {
101         return dimensionY;
102     }
103 
104     /**
105      * Return the width in Z.
106      * @return width in Z
107      */
108     public double getDimensionZ() {
109         return dimensionZ;
110     }
111 
112     /**
113      * Return the position of the detector in global coordinates.
114      * @return the position in global coordinates
115      */
116     public Hep3Vector getPosition() {
117         return position;
118     }
119     
120     /**
121      * Return the rotation of the detector in global coordinates.
122      * @return the rotation of the detector
123      */
124     public IRotation3D getRotation() {
125         return rotation;
126     }
127 
128     /**
129      * Create an outline of the detector's envelope volume in HepRep format for display in Wired.
130      */
131     public void appendHepRep(HepRepFactory factory, HepRep heprep) {
132         
133         HepRepInstanceTree instanceTree = heprep.getInstanceTreeTop("Detector", "1.0");
134         HepRepTypeTree typeTree = heprep.getTypeTree("DetectorType", "1.0");
135 
136         HepRepType ec = typeTree.getType("Endcap");
137         HepRepType type = factory.createHepRepType(ec, getName());
138 
139         // Set color.
140         type.addAttValue("color", getVisAttributes().getColor());
141 
142         // Set shape.
143         type.addAttValue("drawAs", "Prism");
144 
145         HepRepInstance instance = factory.createHepRepInstance(instanceTree, type);
146       
147         /* x points */
148         double x1 = getDimensionX() / 2;
149         double x2 = -getDimensionX() / 2;
150 
151         /* y points */
152         double y1 = getDimensionY() / 2;
153         double y2 = -getDimensionY() / 2;
154 
155         /* z points */
156         double z1 = getDimensionZ() / 2;
157         double z2 = -getDimensionZ() / 2;
158 
159         /* Add HepRep points to the instance. */
160         addHepRepPoint(factory, instance, x1, y1, z1);
161         addHepRepPoint(factory, instance, x1, y2, z1);
162         addHepRepPoint(factory, instance, x2, y2, z1);
163         addHepRepPoint(factory, instance, x2, y1, z1);        
164         addHepRepPoint(factory, instance, x1, y1, z2);
165         addHepRepPoint(factory, instance, x1, y2, z2);
166         addHepRepPoint(factory, instance, x2, y2, z2);
167         addHepRepPoint(factory, instance, x2, y1, z2);              
168     }
169     
170     /**
171      * Get the number of sides.
172      * @return the number of sides
173      */
174     public int getNumberOfSides() {
175         return DEFAULT_NSIDES;
176     }
177 
178     /**
179      * Get the section phi, which is 0 because test beams do not have modules in phi.
180      * @return The section phi which is 0 for test beams.
181      */
182     public double getSectionPhi() {
183         return 0;
184     }
185 
186     /**
187      * This method is not implemented for this type.
188      * @throw UnsupportedOperationException if this method is called
189      */
190     public double getInnerZ() {
191         throw new UnsupportedOperationException("Method not implemented.");
192     }
193 
194     /**
195      * This method is not implemented for this type.
196      * @throw UnsupportedOperationException if this method is called
197      */
198     public double getOuterZ() {
199         throw new UnsupportedOperationException("Method not implemented.");
200     }
201 
202     /**
203      * Get the outer radius of the envelope volume.     
204      * @return The outer radius.
205      */
206     public double getOuterRadius() {
207         return radius;
208     }
209 
210     /**
211      * Get the inner radius of the TestBeam, which is always 0.
212      * @return The inner radius, which is 0.
213      */
214     public double getInnerRadius() {
215         return 0;
216     }
217 
218     /**
219      * Get the z length of the TestBeam.
220      * @return The z length.
221      */
222     public double getZLength() {
223         return dimensionZ;
224     }
225     
226     /**
227      * Add a point to the HepRep output.
228      * @param factory the HepRepFactory object
229      * @param instance the HepRepInstance object
230      * @param x the x value of the point
231      * @param y the y value of the point
232      * @param z the z value of the point
233      */
234     private void addHepRepPoint(HepRepFactory factory, HepRepInstance instance, double x, double y, double z) {        
235         Hep3Vector point = new BasicHep3Vector(x, y, z);
236         transform.transform(point);
237         factory.createHepRepPoint(instance, point.x(), point.y(), point.z());
238     }
239     
240     /**
241      * Compute the dimensions of the detector.
242      * @param dimensions The XML element containing the dimension settings.
243      * @throws DataConversionException if there was a problem converting from XML values
244      */
245     private void computeDimensions(Element dimensions) throws DataConversionException {
246         dimensionX = dimensions.getAttribute("x").getDoubleValue();
247         dimensionY = dimensions.getAttribute("y").getDoubleValue();
248         dimensionZ = getLayering().getThickness();
249     }
250 
251     /**
252      * Compute the maximum radius of the detector
253      * @return the radius of the detector
254      */
255     private double computeRadius() {
256         return Math.sqrt(Math.pow(dimensionX / 2, 2) + Math.pow(dimensionY / 2, 2));
257     }
258 
259     /**
260      * Set the position from XML data.
261      * @param node the XML element
262      * @throws DataConversionException if there is a problem converting XML parameters
263      */
264     private void setPosition(Element node) throws DataConversionException {
265         Element element = node.getChild("position");
266 
267         double px = 0;
268         double py = 0;
269         double pz = 0;
270         if (element != null) {
271             Attribute attribute = element.getAttribute("x");
272             if (attribute != null) {
273                 px = attribute.getDoubleValue();
274             }
275             attribute = element.getAttribute("y");
276             if (attribute != null) {
277                 py = attribute.getDoubleValue();
278             }
279             attribute = element.getAttribute("z");
280             if (attribute != null) {
281                 pz = attribute.getDoubleValue();
282             }
283         }
284         this.position = new BasicHep3Vector(px, py, pz);
285     }
286     
287     /**
288      * Set the detector's rotation from XML data.
289      * @param node the XML element
290      * @throws DataConversionException if there is a problem converting XML parameters
291      */
292     private void setRotation(Element node) throws DataConversionException {
293         Element element = node.getChild("rotation");
294         double rx, ry, rz;
295         rx = ry = rz = 0.;
296         if (element != null) {
297             if (element.getAttribute("x") != null) {
298                 rx = element.getAttribute("x").getDoubleValue();
299             }
300             if (element.getAttribute("y") != null) {
301                 ry = element.getAttribute("y").getDoubleValue();
302             }
303             if (element.getAttribute("z") != null) {
304                 rz = element.getAttribute("z").getDoubleValue();
305             }
306         }        
307         this.rotation = new RotationPassiveXYZ(rx, ry, rz);
308     }
309 }