View Javadoc

1   package org.lcsim.geometry.compact.converter.lcdd;
2   
3   import java.util.Iterator;
4   
5   import org.jdom.Element;
6   import org.jdom.JDOMException;
7   import org.lcsim.geometry.compact.converter.lcdd.util.Define;
8   import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
9   import org.lcsim.geometry.compact.converter.lcdd.util.Material;
10  import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
11  import org.lcsim.geometry.compact.converter.lcdd.util.PolyhedraRegular;
12  import org.lcsim.geometry.compact.converter.lcdd.util.Position;
13  import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
14  import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
15  import org.lcsim.geometry.compact.converter.lcdd.util.Solids;
16  import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
17  import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
18  import org.lcsim.geometry.layer.LayerStack;
19  import org.lcsim.geometry.layer.Layering;
20  
21  public class PolyhedraEndcapCalorimeter2 extends LCDDSubdetector
22  {
23      public PolyhedraEndcapCalorimeter2(Element node) throws JDOMException
24      {
25          super(node);
26          this.node = node;
27      }
28  
29      public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
30      {
31          Solids solids = lcdd.getSolids();
32          Structure structure = lcdd.getStructure();
33          Volume motherVolume = lcdd.pickMotherVolume(this);
34          Material air = lcdd.getMaterial("Air");
35          Define define = lcdd.getDefine();
36          Rotation identityRotation = define.getRotation("identity_rot");
37          Element staves = node.getChild("staves");
38          
39          String subdetectorName = node.getAttributeValue("name");
40          int id = node.getAttribute("id").getIntValue();
41          
42          if (node.getChild("dimensions") == null)
43              throw new RuntimeException("PolhedraEndcapCalorimeter2 " + subdetectorName
44                      + " is missing required <dimensions> element.");        
45          
46          Element dimensions = node.getChild("dimensions");
47          double zmin = dimensions.getAttribute("zmin").getDoubleValue();
48          double rmin = dimensions.getAttribute("rmin").getDoubleValue();
49          double rmax = dimensions.getAttribute("rmax").getDoubleValue();
50          int numsides = dimensions.getAttribute("numsides").getIntValue();
51          
52          LayerStack layers = Layering.makeLayering(this.node).getLayerStack();
53      
54          // Geant4 interprets rmax as the distance to the polygonal flat.
55          // We want to interpret this as the distance to the point.
56          rmax = rmax*Math.cos(Math.PI/numsides);
57                  
58          double subdetectorThickness = org.lcsim.geometry.layer.LayerFromCompactCnv.computeDetectorTotalThickness(node);                        
59  
60          PolyhedraRegular envelopeSolid = new PolyhedraRegular(subdetectorName + "_envelope", numsides, rmin, rmax, subdetectorThickness);
61          solids.addSolid(envelopeSolid);
62          Volume envelopeVolume = new Volume(subdetectorName + "_volume", envelopeSolid, air);
63                                  
64          int layerNumber = 0;
65          int layerType = 0;
66          double layerZ = -subdetectorThickness/2;
67          for (Iterator<Element> i = node.getChildren("layer").iterator(); i.hasNext();)
68          {
69              Element layerElement = i.next();
70              double layerThickness = layers.getLayer(layerNumber).getThickness();
71              String layerTypeName = subdetectorName + "_layer" + layerType;            
72              if (layerElement.getAttribute("repeat") == null)
73              {
74                  throw new RuntimeException("Missing the repeat number in layering for " + subdetectorName);
75              }
76              PolyhedraRegular layerSolid = new PolyhedraRegular(layerTypeName + "_solid", numsides, rmin, rmax, layerThickness);
77              solids.addSolid(layerSolid);
78              Volume layerVolume = new Volume(layerTypeName + "_volume", layerSolid, air);
79                 
80              int sliceNumber = 0;
81              double sliceZ = -layerThickness/2;
82              for (Iterator j = layerElement.getChildren("slice").iterator(); j.hasNext();)
83              {
84                  String sliceName = layerTypeName + "_slice" + sliceNumber;
85                  Element sliceElement = (Element) j.next();
86                  if (sliceElement.getAttribute("thickness") == null)
87                      throw new RuntimeException("Missing thickness attribute.");
88                  double sliceThickness = sliceElement.getAttribute("thickness").getDoubleValue();
89                  if (sliceElement.getAttribute("material") == null)
90                      throw new RuntimeException("Missing material attribute.");
91                  String materialName = sliceElement.getAttribute("material").getValue();
92                  Material sliceMaterial = lcdd.getMaterial(materialName);
93                  PolyhedraRegular sliceSolid = new PolyhedraRegular(sliceName + "_solid", numsides, rmin, rmax, sliceThickness);
94                  solids.addSolid(sliceSolid);
95                  Volume sliceVolume = new Volume(sliceName + "_volume", sliceSolid, sliceMaterial);
96                  if (sliceElement.getAttribute("sensitive") != null)
97                  {
98                  	if (sliceElement.getAttribute("sensitive").getBooleanValue() == true)
99                  	{
100                 		sliceVolume.setSensitiveDetector(sens);
101                 	}
102                 }
103                 
104                 // Visualization of slice.
105                 this.setVisAttributes(lcdd, sliceElement, sliceVolume);
106                 //if (sliceElement.getAttribute("vis") != null)
107                 //{
108                 //    sliceVolume.setVisAttributes(lcdd.getVisAttributes(.getAttributeValue("vis")));
109                 //}
110                 structure.addVolume(sliceVolume);
111                 sliceZ += sliceThickness/2;
112                 Position slicePosition = new Position(sliceName + "_position", 0, 0, sliceZ);
113                 define.addPosition(slicePosition);
114                 sliceZ += sliceThickness/2;
115                 PhysVol slicePhysVol = new PhysVol(sliceVolume, layerVolume, slicePosition, identityRotation);
116                 slicePhysVol.addPhysVolID("slice", sliceNumber);
117                 sliceNumber++;
118             }
119             
120             // Visualization of layer.
121             if (layerElement.getAttribute("vis") != null)
122             {
123                 layerVolume.setVisAttributes(lcdd.getVisAttributes(layerElement.getAttributeValue("vis")));
124             }            
125             
126             sliceNumber = 0;
127             structure.addVolume(layerVolume);        
128             int repeat = (int)layerElement.getAttribute("repeat").getDoubleValue();
129             if (repeat <= 0)
130                 throw new RuntimeException("The repeat value of " + repeat + " is invalid.");          
131             for ( int j=0; j<repeat; j++)
132             {
133                 String physLayerName = subdetectorName + "_layer" + layerNumber;
134                 layerZ += layerThickness/2;
135                 Position layerPosition = new Position(physLayerName + "_position", 0, 0, layerZ);
136                 define.addPosition(layerPosition);
137                 PhysVol layerPhysVol = new PhysVol(layerVolume, envelopeVolume, layerPosition, identityRotation);
138                 layerPhysVol.addPhysVolID("layer", layerNumber);
139                 layerZ += layerThickness/2;
140                 ++layerNumber;
141             }
142             ++layerType;            
143         }
144                 
145         // The envelope volume is complete.        
146         structure.addVolume(envelopeVolume);
147         
148         // Set envelope volume attributes.
149         setAttributes(lcdd, node, envelopeVolume);
150                 
151         // Positive endcap.
152         
153         double zrot = Math.PI / numsides;
154         PhysVol physvol = new PhysVol(envelopeVolume);
155         physvol.setZ(zmin+subdetectorThickness/2);
156         physvol.addPhysVolID("system",id);
157         physvol.addPhysVolID("barrel",1);        
158         Rotation positiveEndcapRotation = new Rotation(subdetectorName + "_positive");
159         positiveEndcapRotation.setZ(zrot);
160         lcdd.getDefine().addRotation(positiveEndcapRotation);
161         physvol.setRotation(positiveEndcapRotation);        
162         motherVolume.addPhysVol(physvol);
163         
164         // Negative endcap.
165         
166         // Assume 2 endcaps but check for setting.
167         boolean reflect = true;
168         if (node.getAttribute("reflect") != null )
169         {
170         	reflect = node.getAttribute("reflect").getBooleanValue();
171         }
172         	
173         if (reflect)
174         {
175             PhysVol physvol2 = new PhysVol(envelopeVolume);
176             physvol2.setZ(-zmin-subdetectorThickness/2);
177             Rotation negativeEndcapRotation = new Rotation(subdetectorName + "_negative");
178             lcdd.getDefine().addRotation(negativeEndcapRotation);
179             negativeEndcapRotation.setX(Math.PI);
180             negativeEndcapRotation.setZ(zrot);
181             
182             physvol2.setRotation(negativeEndcapRotation);
183             physvol2.addPhysVolID("system",id);
184             physvol2.addPhysVolID("barrel",2);
185             motherVolume.addPhysVol(physvol2);
186         }
187     }
188     
189     public boolean isCalorimeter()
190     {
191         return true;
192     }    
193 }