View Javadoc

1   package org.lcsim.detector.converter.heprep;
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.HepRepTreeID;
8   import hep.graphics.heprep.HepRepType;
9   import hep.graphics.heprep.HepRepTypeTree;
10  import hep.graphics.heprep.HepRepWriter;
11  import hep.physics.vec.BasicHep3Vector;
12  import hep.physics.vec.Hep3Vector;
13  
14  import java.awt.Color;
15  import java.io.FileOutputStream;
16  import java.util.List;
17  
18  import org.lcsim.detector.DetectorElementStore;
19  import org.lcsim.detector.IDetectorElement;
20  import org.lcsim.detector.IGeometryInfo;
21  import org.lcsim.detector.solids.IPolyhedron;
22  import org.lcsim.detector.solids.ISolid;
23  import org.lcsim.detector.solids.IsoscelesTrapezoid;
24  import org.lcsim.detector.solids.Point3D;
25  import org.lcsim.detector.solids.RegularPolygon;
26  import org.lcsim.detector.solids.RightIsoscelesTrapezoid;
27  import org.lcsim.detector.solids.RightRegularPolyhedron;
28  import org.lcsim.detector.solids.Tube;
29  
30  /**
31   * This class converters from an {@link org.lcsim.detector.IDetectorElement} to an
32   * in-memory HepRep description.
33   * 
34   * @see org.lcsim.detector.IDetectorElement
35   * @see hep.graphics.heprep
36   * 
37   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
38   * @version $Id: DetectorElementToHepRepConverter.java,v 1.25 2010/12/03 01:20:24 jeremy Exp $
39   */
40  public class DetectorElementToHepRepConverter
41  {
42      /**
43       * This is the primary conversion method. It recursively translates a DetectorElement
44       * into the HepRep format.
45       * 
46       * @param detelem The DetectorElement.
47       * @param factory The HepRepFactory object.
48       * @param heprep The HepRep object.
49       * @param parentType The parent HepRepType.
50       * @param currentDepth The current depth of the DetectorElement traversal.
51       * @param maxDepth The max depth of the DetectorElement traversal.
52       * @param endcap True if DetectorElement is an endcap; false if not.
53       */
54      public static void convert( IDetectorElement detelem,
55              HepRepFactory factory,
56              HepRep heprep,
57              HepRepType parentType,
58              int currentDepth,
59              int maxDepth,
60              boolean endcap,
61              Color color )
62      {
63          // Check for null DetectorElement.  Fail silently because this can 
64          // happen if component has no detailed geometry representation.
65          if ( detelem == null )
66              //throw new RuntimeException( "DetectorElement points to null!" );
67              return;
68  
69          // If we are at max depth, then don't continue.
70          // Since depth starts at 0, less than or equal is used.
71          if ( maxDepth != -1 && currentDepth >= maxDepth )
72              return;
73          
74          //System.out.println("converting: " + detelem.getName());
75  
76          // Get the detector InstanceTree and TypeTree.
77          HepRepInstanceTree instanceTree = heprep.getInstanceTreeTop( "Detector", "1.0" );
78          HepRepTypeTree typeTree = heprep.getTypeTree( "DetectorType", "1.0" );
79  
80          // Find this component's base type.
81          HepRepType baseType;
82          if ( parentType != null )
83          {
84              baseType = parentType;
85          }
86          else
87          {
88              baseType = typeTree.getType( "Barrel" );
89              if ( endcap )
90              {
91                  baseType = typeTree.getType( "Endcap" );
92              }
93          }
94  
95          // Create a type for this DetectorElement.
96          HepRepType newType = factory.createHepRepType( baseType, detelem.getName() );
97          
98          // Assign color to type.
99          if ( color != null )
100         {
101             newType.addAttValue( "color", color );
102             //System.out.println("  color: " + color);
103         }            
104         
105         // Add geometric information to HepRep if there is a geometry
106         // associated with this DetectorElement.
107         if ( detelem.hasGeometryInfo() )
108         {                        
109             IGeometryInfo geo = detelem.getGeometry();
110             ISolid solid = geo.getLogicalVolume().getSolid();
111 
112             if ( solid instanceof IPolyhedron )
113             {
114                 IPolyhedron polyhedron = ( IPolyhedron ) geo.getLogicalVolume()
115                         .getSolid();
116 
117                 newType.addAttValue( "drawAs", "Prism" );
118                                                                 
119                 HepRepInstance instance = factory.createHepRepInstance(
120                         instanceTree,
121                         newType );
122                 
123                 List< Point3D > points = polyhedron.getVertices();
124                 int[] point_ordering = polyhedron.getHepRepVertexOrdering();
125 
126                 for ( int i = 0; i < point_ordering.length; i++ )
127                 {
128                     Hep3Vector p = geo.transformLocalToGlobal( points
129                             .get( point_ordering[ i ] ) );
130                     factory.createHepRepPoint( instance, p.x(), p.y(), p.z() );
131                 }                
132             }
133             else if ( solid instanceof Tube )
134             {                
135                 Tube tube = ( Tube ) geo.getLogicalVolume().getSolid();
136 
137                 newType.addAttValue( "drawAs", "Cylinder" );
138                 
139                 double zmin = -tube.getZHalfLength();
140                 double zmax = tube.getZHalfLength();
141 
142                 Hep3Vector point1 = new BasicHep3Vector( 0, 0, zmin );
143                 Hep3Vector point2 = new BasicHep3Vector( 0, 0, zmax );
144 
145                 point1 = geo.transformLocalToGlobal( point1 );
146                 point2 = geo.transformLocalToGlobal( point2 );
147 
148                 HepRepInstance instance = factory.createHepRepInstance(
149                         instanceTree,
150                         newType );
151                                 
152                 instance.addAttValue( "radius", tube.getInnerRadius() );
153                 factory.createHepRepPoint( instance, point1.x(), point1.y(), point1.z() );
154                 factory.createHepRepPoint( instance, point2.x(), point2.y(), point2.z() );
155 
156                 HepRepInstance instance2 = factory.createHepRepInstance(
157                         instanceTree,
158                         newType );
159                 instance2.addAttValue( "radius", tube.getOuterRadius() );
160                 factory.createHepRepPoint( instance2, point1.x(), point1.y(), point1.z() );
161                 factory.createHepRepPoint( instance2, point2.x(), point2.y(), point2.z() );
162             }
163             else if ( solid instanceof RightRegularPolyhedron )
164             {
165                 RightRegularPolyhedron poly = ( RightRegularPolyhedron ) geo
166                         .getLogicalVolume().getSolid();
167 
168                 newType.addAttValue( "drawAs", "Prism" );
169                                 
170                 HepRepInstance instance = factory.createHepRepInstance(
171                         instanceTree,
172                         newType );
173 
174                 // Outer polygon.
175                 RegularPolygon outerPolygon = poly.getOuterPolygon();
176                 Hep3Vector vertices[] = outerPolygon.getVertices();
177                 double z = poly.getZMin();
178                 for ( int i = 0; i < 2; i++ )
179                 {
180                     for ( int j = 0; j < vertices.length; j++ )
181                     {
182                         Hep3Vector point = vertices[ j ];
183                         Hep3Vector tpoint = new BasicHep3Vector( point.x(), point.y(), z );
184                         tpoint = geo.transformLocalToGlobal( tpoint );
185 
186                         factory.createHepRepPoint(
187                                 instance,
188                                 tpoint.x(),
189                                 tpoint.y(),
190                                 tpoint.z() );
191                     }
192                     z = poly.getZMax();
193                 }
194 
195                 // Inner polygon.
196                 if ( poly.isHollow() )
197                 {
198                     instance = factory.createHepRepInstance( instanceTree, newType );
199                     RegularPolygon innerPolygon = poly.getInnerPolygon();
200                     vertices = innerPolygon.getVertices();
201                     z = poly.getZMin();
202                     for ( int i = 0; i < 2; i++ )
203                     {
204                         for ( int j = 0; j < vertices.length; j++ )
205                         {
206                             Hep3Vector point = vertices[ j ];
207                             Hep3Vector tpoint = new BasicHep3Vector( point.x(),
208                                                                      point.y(),
209                                                                      z );
210                             tpoint = geo.transformLocalToGlobal( tpoint );
211 
212                             factory.createHepRepPoint(
213                                     instance,
214                                     tpoint.x(),
215                                     tpoint.y(),
216                                     tpoint.z() );
217                         }
218                         z = poly.getZMax();
219                     }
220                 }
221             }
222             else if ( solid instanceof RightIsoscelesTrapezoid )
223             {
224                 RightIsoscelesTrapezoid poly = ( RightIsoscelesTrapezoid ) geo
225                         .getLogicalVolume().getSolid();
226 
227                 newType.addAttValue( "drawAs", "Prism" );
228                                 
229                 HepRepInstance instance = factory.createHepRepInstance(
230                         instanceTree,
231                         newType );
232 
233                 // Outer polygon.
234                 IsoscelesTrapezoid face = poly.face();
235                 Hep3Vector vertices[] = face.getVertices();
236                 double z = poly.zMin();
237                 for ( int i = 0; i < 2; i++ )
238                 {
239                     for ( int j = 0; j < vertices.length; j++ )
240                     {
241                         Hep3Vector point = vertices[ j ];
242                         Hep3Vector tpoint = new BasicHep3Vector( point.x(), point.y(), z );
243                         tpoint = geo.transformLocalToGlobal( tpoint );
244 
245                         factory.createHepRepPoint(
246                                 instance,
247                                 tpoint.x(),
248                                 tpoint.y(),
249                                 tpoint.z() );
250                     }
251                     z = poly.zMax();
252                 }
253             }
254         }
255         
256         // Process children recursively.
257         if ( detelem.hasChildren() )
258         {
259             for ( IDetectorElement child : detelem.getChildren() )
260             {
261                 // Passing color is not necessary, as child types
262                 // should pickup from their parent.
263                 DetectorElementToHepRepConverter.convert(
264                         child,
265                         factory,
266                         heprep,
267                         newType,
268                         currentDepth + 1,
269                         maxDepth,
270                         endcap,
271                         null );
272             }
273         }
274     }
275 
276     /**
277      * Convert from DetectorElements to HepRep using default depth parameters.
278      * 
279      * @param detelem
280      * @param factory
281      * @param heprep
282      * @param endcap
283      */
284     public static void convert( IDetectorElement detelem,
285             HepRepFactory factory,
286             HepRep heprep,
287             boolean endcap,
288             Color color )
289     {
290         convert( detelem, factory, heprep, -1, endcap, color );
291     }
292 
293     /**
294      * Convert from DetectorElements to HepRep, specifying the max depth parameter.
295      * 
296      * @param detelem
297      * @param factory
298      * @param heprep
299      * @param maxDepth
300      * @param endcap
301      */
302     public static void convert( IDetectorElement detelem,
303             HepRepFactory factory,
304             HepRep heprep,
305             int maxDepth,
306             boolean endcap,
307             Color color )
308     {
309         convert( detelem, factory, heprep, null, 0, maxDepth, endcap, color );
310     }
311 
312     // FIXME Duplicate constants.
313     public final static String HITS_LAYER = "Hits";
314     public final static String PARTICLES_LAYER = "Particles";
315 
316     // This method is used by some test cases but shouldn't be used in
317     // any "production" code due to a few oddities/bugs.
318     //
319     // TODO This needs to put components under correct Barrel or Endcap type.
320     // Currently, everything goes into Barrel.
321     public static void writeHepRep( String filepath ) throws Exception
322     {
323         HepRepFactory factory = HepRepFactory.create();
324         HepRep root = factory.createHepRep();
325 
326         // detector
327 
328         HepRepTreeID treeID = factory.createHepRepTreeID( "DetectorType", "1.0" );
329         HepRepTypeTree typeTree = factory.createHepRepTypeTree( treeID );
330         root.addTypeTree( typeTree );
331 
332         HepRepInstanceTree instanceTree = factory.createHepRepInstanceTree(
333                 "Detector",
334                 "1.0",
335                 typeTree );
336         root.addInstanceTree( instanceTree );
337 
338         String detectorLayer = "Detector";
339         root.addLayer( detectorLayer );
340 
341         HepRepType barrel = factory.createHepRepType( typeTree, "Barrel" );
342         barrel.addAttValue( "layer", detectorLayer );
343         HepRepType endcap = factory.createHepRepType( typeTree, "Endcap" );
344         endcap.addAttValue( "layer", detectorLayer );
345 
346         for ( IDetectorElement de : DetectorElementStore.getInstance() )
347         {
348             DetectorElementToHepRepConverter.convert( de, factory, root, false, null );
349         }
350 
351         // end detector
352 
353         root.addLayer( PARTICLES_LAYER );
354         root.addLayer( HITS_LAYER );
355         root.addLayer( "axis" );
356 
357         treeID = factory.createHepRepTreeID( "EventType", "1.0" );
358         typeTree = factory.createHepRepTypeTree( treeID );
359         root.addTypeTree( typeTree );
360         instanceTree = factory.createHepRepInstanceTree( "Event", "1.0", typeTree );
361         root.addInstanceTree( instanceTree );
362 
363         // axis
364 
365         HepRepType axis = factory.createHepRepType( typeTree, "axis" );
366         axis.addAttValue( "drawAs", "Line" );
367         axis.addAttValue( "layer", "axis" );
368 
369         HepRepType xaxis = factory.createHepRepType( axis, "xaxis" );
370         xaxis.addAttValue( "color", Color.RED );
371         xaxis.addAttValue( "fill", true );
372         xaxis.addAttValue( "fillColor", Color.RED );
373         HepRepInstance x = factory.createHepRepInstance( instanceTree, xaxis );
374         factory.createHepRepPoint( x, 0, 0, 0 );
375         factory.createHepRepPoint( x, 1000, 0, 0 );
376 
377         HepRepType yaxis = factory.createHepRepType( axis, "yaxis" );
378         yaxis.addAttValue( "color", Color.GREEN );
379         yaxis.addAttValue( "fill", true );
380         yaxis.addAttValue( "fillColor", Color.GREEN );
381         HepRepInstance y = factory.createHepRepInstance( instanceTree, yaxis );
382         factory.createHepRepPoint( y, 0, 0, 0 );
383         factory.createHepRepPoint( y, 0, 1000, 0 );
384 
385         HepRepType zaxis = factory.createHepRepType( axis, "zaxis" );
386         zaxis.addAttValue( "color", Color.BLUE );
387         zaxis.addAttValue( "fill", true );
388         zaxis.addAttValue( "fillColor", Color.BLUE );
389         HepRepInstance z = factory.createHepRepInstance( instanceTree, zaxis );
390         factory.createHepRepPoint( z, 0, 0, 0 );
391         factory.createHepRepPoint( z, 0, 0, 1000 );
392 
393         // done axis
394 
395         HepRepWriter writer = HepRepFactory.create().createHepRepWriter(
396                 new FileOutputStream( filepath ),
397                 false,
398                 false );
399         writer.write( root, "test" );
400         writer.close();
401     }
402 }