1 package org.lcsim.geometry.compact.converter.html;
2
3 import java.text.DecimalFormat;
4 import java.text.SimpleDateFormat;
5 import java.util.ArrayList;
6 import java.util.Calendar;
7 import java.util.List;
8 import java.util.Map;
9
10 import org.jdom.Element;
11 import org.lcsim.detector.IDetectorElement;
12 import org.lcsim.detector.tracker.silicon.SiSensor;
13 import org.lcsim.geometry.Calorimeter;
14 import org.lcsim.geometry.compact.Constant;
15 import org.lcsim.geometry.compact.Detector;
16 import org.lcsim.geometry.compact.Field;
17 import org.lcsim.geometry.compact.Header;
18 import org.lcsim.geometry.compact.Readout;
19 import org.lcsim.geometry.compact.Segmentation;
20 import org.lcsim.geometry.compact.Subdetector;
21 import org.lcsim.geometry.field.Solenoid;
22 import org.lcsim.geometry.layer.Layer;
23 import org.lcsim.geometry.layer.LayerSlice;
24 import org.lcsim.geometry.layer.LayerStack;
25 import org.lcsim.geometry.subdetector.AbstractLayeredSubdetector;
26 import org.lcsim.geometry.subdetector.PolyconeSupport;
27 import org.lcsim.geometry.subdetector.SiTrackerBarrel;
28 import org.lcsim.geometry.subdetector.SiTrackerEndcap;
29 import org.lcsim.geometry.subdetector.SiTrackerEndcap2;
30 import org.lcsim.geometry.subdetector.TubeSegment;
31
32
33
34
35
36
37
38
39
40
41
42 class HtmlConverter
43 {
44 static DecimalFormat layerForm = new DecimalFormat( "#.##" );
45 static DecimalFormat lenForm = new DecimalFormat( "#.######" );
46 static DecimalFormat geomForm = new DecimalFormat( "#.##");
47
48 private HtmlConverter()
49 {}
50
51 public static Element convert( Detector d )
52 {
53
54 Detector detector = ( org.lcsim.geometry.compact.Detector ) d;
55
56
57 Element root = new Element( "html" );
58
59
60 Element head = new Element( "head" );
61 String detectorName = detector.getName();
62 Element title = new Element( "title" );
63 title.setText( detectorName );
64 head.addContent( title );
65 root.addContent( head );
66
67
68 Element body = new Element( "body" );
69 root.addContent( body );
70
71
72 Element tbl = new Element( "table" );
73 tbl.setAttribute( "cellspacing", "25" );
74 tbl.setAttribute( "width", "100%" );
75 body.addContent( tbl );
76
77
78 Element td = addLayoutRow( tbl );
79
80
81 detectorHeader( td, detector );
82
83
84 td = addLayoutRow( tbl );
85
86
87 Element p = new Element( "p" );
88 p.addContent( new Link( "Go to Constants", "#defines" ) );
89 td.addContent( p );
90 p = new Element( "p" );
91 p.addContent( new Link( "Go to Fields", "#fields" ) );
92 td.addContent( p );
93
94
95 List<String> subdets = new ArrayList<String>();
96 subdets.addAll( detector.getSubdetectors().keySet() );
97 java.util.Collections.sort( subdets );
98
99
100 td = addLayoutRow( tbl );
101
102
103 subdetectorIndex( td, detector, subdets );
104
105
106 td = addLayoutRow( tbl );
107
108
109 sysIdIndex( td, detector );
110
111
112 td = addLayoutRow( tbl );
113
114
115 readoutIndex( td, detector );
116
117
118 td = addLayoutRow( tbl );
119
120
121 lengthTable( td, detector, subdets );
122
123
124 addHeader2( td, "Subdetector Details" );
125
126
127 for ( String subdetName : subdets )
128 {
129
130 td = addLayoutRow( tbl );
131
132
133 subdetector( td, detector.getSubdetector( subdetName ) );
134 }
135
136
137 td = addLayoutRow( tbl );
138
139
140 defines( td, detector );
141
142
143 td = addLayoutRow( tbl );
144
145
146 fields( td, detector );
147
148
149 td = addLayoutRow( tbl );
150
151
152 timestamp( td );
153
154 return root;
155 }
156
157 private static Element layers( Subdetector subdet )
158 {
159 Element tbl = null;
160 if ( subdet instanceof AbstractLayeredSubdetector )
161 {
162 AbstractLayeredSubdetector layered = ( AbstractLayeredSubdetector ) subdet;
163 LayerStack layers = layered.getLayering().getLayerStack();
164 if ( layers.getNumberOfLayers() > 0 )
165 {
166 tbl = new Element( "table" );
167 tbl.setAttribute( "border", "1" );
168
169 Layer currentLayer = null;
170 int bottomLayer = 0;
171 int topLayer = 0;
172 for ( int i = 0, nlayers = layers.getNumberOfLayers(); i < nlayers; i++ )
173 {
174 if ( currentLayer == null )
175 {
176 currentLayer = layers.getLayer( i );
177 }
178
179
180 if ( currentLayer.getThickness() != layers.getLayer( i )
181 .getThickness() || i == nlayers - 1 )
182 {
183 if ( i == nlayers - 1 )
184 topLayer = i;
185 else
186 topLayer = i - 1;
187
188
189 if ( topLayer == -1 )
190 topLayer = 0;
191
192 Element sliceTbl = new Element( "table" );
193 sliceTbl.setAttribute( "cellpadding", "2" );
194
195 for ( LayerSlice slice : currentLayer.getSlices() )
196 {
197 addRow( sliceTbl,
198 layerForm.format( slice.getThickness() ) + " mm",
199 slice.getMaterial().getName(),
200 slice.isSensitive() ? new Element("i").addContent( "sensor") : " " );
201 }
202
203 addRow( tbl, bottomLayer + " - " + topLayer, sliceTbl );
204
205 bottomLayer = i;
206 topLayer = i;
207 currentLayer = layers.getLayer( i );
208 }
209 }
210 }
211 }
212
213 return tbl;
214 }
215
216 private static void timestamp( Element parent )
217 {
218 Calendar cal = Calendar.getInstance();
219 SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
220 String ts = new String( "Generated by GeomConverter at " + sdf.format( cal
221 .getTime() ) + " by user " + System.getProperty( "user.name" ) + "." );
222
223 parent.addContent( new Element( "p" ).setText( ts ) );
224 }
225
226 private static void lengthTable( Element parent,
227 Detector detector,
228 List<String> subdets )
229 {
230
231 addHeader2( parent, "Radiation and Interaction Lengths" );
232
233 Element tbl = new Element( "table" );
234 parent.addContent( tbl );
235 tbl.setAttribute( "border", "1" );
236 tbl.setAttribute( "cellpadding", "2" );
237
238
239 addRow( tbl,
240 new Element( "b" ).setText( "Subdetector" ),
241 new Element( "b" ).setText( "Radiation Lengths" ),
242 new Element( "b" ).setText( "Interaction Lengths" ) );
243
244 for ( String subdetName : subdets )
245 {
246 Subdetector subdet = detector.getSubdetector( subdetName );
247 AbstractLayeredSubdetector layers;
248 if ( subdet instanceof AbstractLayeredSubdetector )
249 {
250 layers = ( AbstractLayeredSubdetector ) subdet;
251 addRow( tbl,
252 new Link( subdetName, "#" + subdetName ),
253 lenForm.format( layers.getRadiationLengths() ),
254 lenForm.format( layers.getInteractionLengths() ) );
255 }
256 }
257 }
258
259 private static void sysIdIndex( Element parent, Detector detector )
260 {
261
262 addHeader2( parent, "Subdetectors by System ID" );
263
264
265 Element tbl = new Element( "table" );
266 tbl.setAttribute( "border", "1" );
267 tbl.setAttribute( "cellpadding", "2" );
268 parent.addContent( tbl );
269
270
271 addRow( tbl, new Element( "b" ).setText( "Sys Id" ), new Element( "b" )
272 .setText( "Subdetector" ) );
273
274
275 List<Integer> systemIds = new ArrayList<Integer>();
276 for ( Subdetector subdet : detector.getSubdetectors().values() )
277 {
278 if ( subdet.getSystemID() != 0 )
279 {
280 systemIds.add( subdet.getSystemID() );
281 }
282 }
283
284
285 java.util.Collections.sort( systemIds );
286
287 for ( Integer sysId : systemIds )
288 {
289 Subdetector subdet = detector.getSubdetector( sysId );
290 String subdetName = subdet.getName();
291 addRow( tbl, subdet.getSystemID(), new Link( subdetName, "#" + subdetName ) );
292 }
293 }
294
295 private static void subdetectorIndex( Element parent,
296 Detector detector,
297 List<String> names )
298 {
299
300 addHeader2( parent, "Components" );
301
302
303 Element tbl = new Element( "table" );
304 tbl.setAttribute( "border", "1" );
305 tbl.setAttribute( "cellpadding", "2" );
306 parent.addContent( tbl );
307
308
309 addRow( tbl, new Element( "b" ).setText( "Subdetector" ) );
310
311 for ( String subdetName : names )
312 {
313 Subdetector subdet = detector.getSubdetector( subdetName );
314 String readoutName = "-";
315 if ( subdet.getReadout() != null )
316 {
317 readoutName = subdet.getReadout().getName();
318 }
319
320 addRow( tbl, new Link( subdetName, "#" + subdetName ) );
321 }
322 }
323
324 private static void readoutIndex( Element parent, Detector detector )
325 {
326
327 addHeader2( parent, "Readouts" );
328
329
330 Element tbl = new Element( "table" );
331 tbl.setAttribute( "border", "1" );
332 tbl.setAttribute( "cellpadding", "2" );
333 parent.addContent( tbl );
334
335
336 addRow( tbl,
337 new Element( "b" ).setText( "Readout" ),
338 new Element( "b" ).setText( "Subdetectors" ),
339 new Element( "b" ).setText( "ID Description" ),
340 new Element( "b" ).setText( "Cell Size U x V" ));
341
342
343 List<String> readoutNames = new ArrayList<String>( detector.getReadouts()
344 .keySet() );
345 java.util.Collections.sort( readoutNames );
346
347
348 for ( String readoutName : readoutNames )
349 {
350
351 Readout readout = detector.getReadout( readoutName );
352
353
354 List<Subdetector> subdets = new ArrayList<Subdetector>();
355
356
357 Element span = new Element( "span" );
358 for ( Subdetector subdet : detector.getSubdetectors().values() )
359 {
360
361 if ( subdet.getReadout() == readout )
362 {
363 String subdetName = subdet.getName();
364 span.addContent( new Link( subdetName, "#" + subdetName ) );
365 }
366 }
367
368 String cellSizes = "NA";
369 try
370 {
371 if ( readout.getIDDecoder() instanceof Segmentation )
372 {
373 Segmentation seg = (Segmentation) readout.getIDDecoder();
374 cellSizes = seg.getCellSizeU() + " mm x " + seg.getCellSizeV() + " mm";
375 }
376 }
377 catch ( Exception x )
378 {
379
380 }
381
382
383 addRow( tbl,
384 readout.getName(),
385 span,
386 readout.getIDDecoder().getIDDescription().toString(),
387 cellSizes );
388 }
389 }
390
391 private static void detectorHeader( Element parent, Detector detector )
392 {
393 addHeader2( parent, "Summary" );
394
395 Element tbl = new Element( "table" );
396 tbl.setAttribute( "border", "1" );
397 tbl.setAttribute( "cellpadding", "2" );
398 parent.addContent( tbl );
399
400 Header header = detector.getHeader();
401
402 addLabeledRow( tbl, "Detector", detector.getName() );
403 addLabeledRow( tbl, "Title", header.getTitle() );
404 addLabeledRow( tbl, "Comment", header.getComment() );
405 addLabeledRow( tbl, "Author", header.getAuthor() );
406 addLabeledRow( tbl, "Status", header.getStatus() );
407 addLabeledRow( tbl, "Version", header.getVersion() );
408 addLabeledRow( tbl,
409 "Documentation",
410 header.getURL().equals( "NONE" ) ? "NONE" : new Link( header.getURL() ) );
411 addLabeledRow( tbl,
412 "Zip File",
413 new Link( "http://www.lcsim.org/detectors/" + detector.getName() + ".zip" ) );
414 }
415
416 private static void subdetector( Element parent, Subdetector subdet )
417 {
418
419 bookmark( parent, subdet.getName() );
420
421
422 Element tbl = new Element( "table" );
423 tbl.setAttribute( "border", "1" );
424 tbl.setAttribute( "width", "80%" );
425 tbl.setAttribute( "cellpadding", "2" );
426 parent.addContent( tbl );
427
428
429 addLabeledRow( tbl, "Subdetector", subdet.getName() );
430 addLabeledRow( tbl, "System ID", subdet.getSystemID() );
431 addLabeledRow( tbl, "Type", subdet.isCalorimeter() ? "Calorimeter" : "Tracker" );
432 addLabeledRow( tbl, "Class", subdet.getClass().getSimpleName() );
433 addLabeledRow( tbl, "Endcap", subdet.isEndcap() ? true : false );
434 addLabeledRow( tbl, "Readout", subdet.getReadout() != null ? subdet.getReadout()
435 .getName() : "NONE" );
436 addLabeledRow( tbl, "Tracking Vol", subdet.isInsideTrackingVolume() );
437 addLabeledRow( tbl, "ID Description", subdet.getReadout() != null ? subdet
438 .getIDDecoder().getIDDescription().toString() : "NONE" );
439
440 if ( subdet instanceof AbstractLayeredSubdetector )
441 {
442 AbstractLayeredSubdetector layers = ( AbstractLayeredSubdetector ) subdet;
443
444 addLabeledRow( tbl, "Number Of Layers", layers.getNumberOfLayers() );
445 addLabeledRow( tbl, "Interaction Lengths", lenForm.format( layers.getInteractionLengths() ) );
446 addLabeledRow( tbl, "Radiation Lengths", lenForm.format( layers.getRadiationLengths() ) );
447 }
448
449
450 if ( subdet instanceof Calorimeter )
451 {
452 Calorimeter cal = ( Calorimeter ) subdet;
453 addLabeledRow( tbl, "Calorimeter Type", cal.getCalorimeterType().toString() );
454 addLabeledRow( tbl, "Number Of Sides", cal.getNumberOfSides() );
455 addLabeledRow( tbl, "Inner Radius", geomForm.format( cal.getInnerRadius() ) + " mm" );
456 addLabeledRow( tbl, "Outer Radius", geomForm.format( cal.getOuterRadius() ) + " mm" );
457 addLabeledRow( tbl, "Z Length", geomForm.format( cal.getZLength() ) + " mm" );
458 addLabeledRow( tbl, "Inner Z", geomForm.format( cal.getInnerZ() ) + " mm" );
459 addLabeledRow( tbl, "Outer Z", geomForm.format( cal.getOuterZ() ) + " mm" );
460 addLabeledRow( tbl, "Section Phi", geomForm.format( cal.getSectionPhi() ) + " radians" );
461 if ( subdet.getReadout() != null && subdet.getReadout().getIDDecoder() instanceof Segmentation )
462 {
463 Segmentation seg = ( Segmentation ) subdet.getReadout().getIDDecoder();
464 addLabeledRow( tbl, "Segmentation Type", seg.getClass().getSimpleName() );
465 }
466
467 try
468 {
469 addLabeledRow( tbl, "Cell Size U", subdet.getReadout() != null ? cal
470 .getCellSizeU() + " mm" : "NA" );
471 addLabeledRow( tbl, "Cell Size V", subdet.getReadout() != null ? cal
472 .getCellSizeV() + " mm" : "NA" );
473 }
474 catch ( IndexOutOfBoundsException x )
475 {
476
477
478 }
479
480
481 if ( subdet.getLayering() != null && subdet.getLayering().getNumberOfLayers() > 0 )
482 {
483 Element layerTbl = layers( subdet );
484
485 addLabeledRow( tbl, "Layers", layerTbl );
486 }
487 }
488 else if ( subdet instanceof TubeSegment )
489 {
490 TubeSegment tube = (TubeSegment) subdet;
491 addLabeledRow( tbl, "Inner Radius", geomForm.format( tube.getInnerRadius() ) + " mm" );
492 addLabeledRow( tbl, "Outer Radius", geomForm.format( tube.getOuterRadius() ) + " mm" );
493 addLabeledRow( tbl, "Z Half Length", geomForm.format( tube.getZHalfLength() ) + " mm" );
494 }
495 else if ( subdet instanceof PolyconeSupport )
496 {
497 Element planesTbl = new Element("table");
498 planesTbl.setAttribute( "border", "1" );
499 planesTbl.setAttribute( "cellpadding", "2");
500
501 PolyconeSupport poly = (PolyconeSupport) subdet;
502
503
504 addRow( planesTbl,
505 new Element( "b" ).setText( "R Min" ),
506 new Element( "b" ).setText( "R Max" ),
507 new Element( "b" ).setText( "Z" ) );
508
509 for ( int i = 0, nplanes = poly.getNumberOfZPlanes(); i < nplanes; i++ )
510 {
511 addRow( planesTbl,
512 geomForm.format( poly.getZPlane( i ).getRMin() ),
513 geomForm.format( poly.getZPlane( i ).getRMax() ),
514 geomForm.format( poly.getZPlane( i ).getZ() ) );
515 }
516
517 addLabeledRow( tbl, "Z Planes", planesTbl );
518 }
519
520 else if ( subdet instanceof SiTrackerBarrel || subdet instanceof SiTrackerEndcap || subdet instanceof SiTrackerEndcap2)
521 {
522 IDetectorElement de = subdet.getDetectorElement();
523
524 List<SiSensor> sensors = de.findDescendants( SiSensor.class );
525 int nsensors = sensors.size();
526
527 addLabeledRow( tbl, "Sensors", Integer.toString( nsensors ) );
528 }
529 }
530
531 private static void defines( Element parent, Detector detector )
532 {
533 bookmark( parent, "defines" );
534
535 addHeader2( parent, "Constants" );
536
537 Element tbl = new Element( "table" );
538 tbl.setAttribute( "border", "1" );
539 tbl.setAttribute( "width", "50%" );
540 tbl.setAttribute( "cellpadding", "1" );
541 parent.addContent( tbl );
542
543
544 Map<String, Constant> cmap = detector.getConstants();
545 List<String> constants = new ArrayList<String>( cmap.keySet() );
546 java.util.Collections.sort( constants );
547
548 for ( String key : constants )
549 {
550 addLabeledRow( tbl, key, cmap.get( key ).getValue() );
551 }
552 }
553
554 private static void fields( Element parent, Detector detector )
555 {
556 bookmark( parent, "fields" );
557
558 addHeader2( parent, "Fields" );
559
560 Element tbl = new Element( "table" );
561 parent.addContent( tbl );
562 tbl.setAttribute( "border", "1" );
563 tbl.setAttribute( "width", "50%" );
564
565 for ( Map.Entry<String, Field> entry : detector.getFields().entrySet() )
566 {
567 Field field = entry.getValue();
568 addLabeledRow( tbl, "Field", entry.getKey() );
569 addLabeledRow( tbl, "Type", field.getClass().getSimpleName() );
570 if ( field instanceof Solenoid )
571 {
572 Solenoid solenoid = ( Solenoid ) field;
573 addLabeledRow( tbl, "Inner Field", solenoid.getInnerField()[ 2 ] + " Tesla" );
574 addLabeledRow( tbl, "Outer Field", solenoid.getOuterField()[ 2 ] + " Tesla" );
575 addLabeledRow( tbl, "Z Max", solenoid.getZMax() + " mm" );
576 addLabeledRow( tbl, "Outer Radius 2", solenoid.getOuterRadius2() + " mm" );
577 }
578 }
579 }
580
581 private static void addHeader2( Element parent, String text )
582 {
583 Element h = new Element( "h2" );
584 h.setText( text );
585 parent.addContent( h );
586 }
587
588 private static Element addLayoutRow( Element tbl )
589 {
590 Element tr = new Element( "tr" );
591 tbl.addContent( tr );
592 Element td = new Element( "td" );
593 tr.addContent( td );
594 return td;
595 }
596
597 private static void addRow( Element table, Object... values )
598 {
599 if ( !table.getName().equals( "table" ) )
600 {
601 throw new RuntimeException( "Element is not a <table>." );
602 }
603
604 Element tr = new Element( "tr" );
605 table.addContent( tr );
606
607 for ( Object value : values )
608 {
609 Element td = new Element( "td" );
610 td.setAttribute( "valign", "top" );
611 if ( value instanceof String )
612 td.setText( ( String ) value );
613 else if ( value instanceof Element )
614 td.addContent( ( Element ) value );
615 else
616 td.setText( value.toString() );
617 tr.addContent( td );
618 }
619 }
620
621 private static void addLabeledRow( Element table, String label, Object value )
622 {
623 if ( !table.getName().equals( "table" ) )
624 {
625 throw new RuntimeException( "Element is not a <table>." );
626 }
627
628 Element tr = new Element( "tr" );
629 table.addContent( tr );
630
631
632 Element td = new Element( "td" );
633 td.setAttribute( "width", "25%" );
634 td.setAttribute( "valign", "top" );
635 Element b = new Element( "b" );
636 td.addContent( b );
637 b.setText( label );
638 tr.addContent( td );
639
640
641 td = new Element( "td" );
642 td.setAttribute( "valign", "top" );
643 tr.addContent( td );
644 if ( value instanceof String )
645 td.setText( ( String ) value );
646 else if ( value instanceof Element )
647 td.addContent( ( Element ) value );
648 else
649 td.setText( value.toString() );
650 }
651
652 private static void bookmark( Element parent, String text )
653 {
654 Element a = new Element( "a" );
655 a.setAttribute( "name", text );
656 parent.addContent( a );
657 }
658
659 private static class Link extends Element
660 {
661 Link( String label, String url )
662 {
663 super( "a" );
664 this.setAttribute( "href", url );
665 this.setText( label );
666 }
667
668 Link( String url )
669 {
670 super( "a" );
671 this.setAttribute( "href", url );
672 this.setText( url );
673 }
674 }
675 }