View Javadoc

1   /*
2    * LayeredSubdetector.java
3    * 
4    * Created on July 17, 2005, 5:49 PM
5    */
6   
7   package org.lcsim.geometry.subdetector;
8   
9   import hep.physics.vec.BasicHep3Vector;
10  import hep.physics.vec.Hep3Vector;
11  
12  import java.util.ArrayList;
13  import java.util.HashMap;
14  import java.util.List;
15  import java.util.Map;
16  
17  import org.jdom.Element;
18  import org.jdom.JDOMException;
19  import org.lcsim.detector.material.BetheBlochCalculator;
20  import org.lcsim.detector.material.IMaterial;
21  import org.lcsim.geometry.Layered;
22  import org.lcsim.geometry.layer.Layer;
23  import org.lcsim.geometry.layer.LayerSlice;
24  import org.lcsim.geometry.layer.Layering;
25  import org.lcsim.material.Material;
26  import org.lcsim.material.MaterialState;
27  
28  /**
29   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
30   * @version $Id: AbstractLayeredSubdetector.java,v 1.10 2011/03/11 19:22:20 jeremy Exp $
31   */
32  abstract public class AbstractLayeredSubdetector extends AbstractSubdetector implements Layered
33  {
34      protected Layering layering;
35  
36      private List<Double> nrad;
37      private List<Double> nlam;
38      private List<Double> de;
39      private Map<String, Double> dedxmap = new HashMap<String, Double>();
40      
41      private double intLens;
42      private double radLens;
43  
44      /**
45       * Creates a new instance of a LayeredSubdetector
46       */
47      public AbstractLayeredSubdetector( Element node ) throws JDOMException
48      {
49          super( node );
50          build( node );
51  
52          // Initialize parameter arrays using layer count.
53          nrad = new ArrayList<Double>( this.getLayering().getNumberOfLayers() );
54          de = new ArrayList<Double>( this.getLayering().getNumberOfLayers() );
55          nlam = new ArrayList<Double>( this.getLayering().getNumberOfLayers() );
56  
57          // Compute layer derived quantities.
58          computeLayerParameters();
59      }
60  
61      private void build( Element node ) throws JDOMException
62      {
63          try
64          {
65              // Setup layering object.
66              layering = org.lcsim.geometry.layer.Layering.makeLayering( node );
67          }
68          catch ( JDOMException x )
69          {
70              throw new RuntimeException( x );
71          }
72      }
73  
74      public boolean isLayered()
75      {
76          return true;
77      }
78  
79      public Layering getLayering()
80      {
81          return layering;
82      }
83      
84      public double getTotalThickess()
85      {
86          return layering.getThickness();
87      }
88  
89      protected void setLayering( Layering layering )
90      {
91          // May only be called once at initialization time.
92          if ( this.layering == null )
93              this.layering = layering;
94      }
95  
96      public Layer getLayer( int layern )
97      {
98          return this.layering.getLayer( layern );
99      }
100 
101     public int getNumberOfLayers()
102     {
103         return this.layering.getLayerCount();
104     }
105 
106     public double getDistanceToLayer( int layern )
107     {
108         return this.layering.getDistanceToLayer( layern );
109     }
110 
111     public double getDistanceToSensor( int layern )
112     {
113         return this.layering.getDistanceToLayerSensorFront( layern );
114     }
115 
116     public double getLayerThickness( int layern )
117     {
118         return this.layering.getLayer( layern ).getThickness();
119     }
120 
121     public double getSensorThickness( int layern )
122     {
123         return this.layering.getLayer( layern ).getSensorThickness();
124     }
125 
126     /**
127      * Compute the radiation and interaction lengths for each layer of this subdetector.
128      * FIXME Access to the dedx information by material name should be moved into
129      * IMaterial interface because map is duplicated across subdetectors. The map could
130      * also be made static.
131      */    
132     private void computeLayerParameters()
133     {
134         // System.out.println("nlayers = " + this.getLayering().getNumberOfLayers());
135 
136         // IMaterialStore ms = MaterialStore.getInstance();
137         int nlayers = this.getNumberOfLayers();
138         Hep3Vector p = new BasicHep3Vector( 0., 0., 100. );
139         for ( int j = 0; j < nlayers; j++ )
140         {
141             // System.out.println("computing layer = " + j);
142             Layer layer = getLayering().getLayer( j );
143             double xrad = 0.;
144             double xlam = 0.;
145             double xde = 0.;
146             for ( LayerSlice slice : layer.getSlices() )
147             {
148                 Material m = slice.getMaterial();
149                 String materialName = m.getName();
150                 double dedx;
151                 if ( dedxmap.containsKey( materialName ) )
152                     dedx = dedxmap.get( materialName ).doubleValue();
153                 else
154                 {
155                     // Kludge to get material state to avoid using IMaterial objects that
156                     // are not instantiated yet.
157                     MaterialState state = m.getState();
158                     IMaterial.State istate = null;
159                     if ( state == MaterialState.GAS )
160                     {
161                         istate = IMaterial.Gas;
162                     }
163                     else if ( state == MaterialState.LIQUID )
164                     {
165                         istate = IMaterial.Liquid;
166                     }
167                     else if ( state == MaterialState.SOLID )
168                     {
169                         istate = IMaterial.Solid;
170                     }
171                     else if ( state == MaterialState.UNKNOWN )
172                     {
173                         istate = IMaterial.Unknown;
174                     }
175                     dedx = BetheBlochCalculator.computeBetheBloch( 
176                             m.getZeff(), 
177                             m.getAeff(), 
178                             m.getDensity(), 
179                             istate, 
180                             Material.DEFAULT_PRESSURE,
181                             Material.DEFAULT_TEMPERATURE,
182                             p, 
183                             105., 
184                             1., 
185                             .01 ) / 10000;
186                     dedxmap.put( materialName, new Double( dedx ) );
187                 }
188                 double dx = slice.getThickness();
189                 xrad += dx / m.getRadiationLengthWithDensity();
190                 xlam += dx / m.getNuclearInteractionLengthWithDensity();
191                 xde += dx * dedx;
192             }
193             nrad.add( j, new Double( xrad / 10. ) );
194             nlam.add( j, new Double( xlam / 10. ) );
195             de.add( j, new Double( xde ) );
196         }
197         
198         // Compute totals for all layers.
199         for ( double lam : nlam )
200         {
201             intLens += lam;
202         }
203         for ( double rad : nrad )
204         {
205             radLens += rad;
206         }
207     }
208     
209     public double getInteractionLengths()
210     {
211         return intLens;
212     }
213     
214     public double getRadiationLengths()
215     {
216         return radLens;
217     }
218 
219     public double getInteractionLengths( int layern )
220     {
221         return nlam.get( layern );
222     }
223 
224     public double getRadiationLengths( int layern )
225     {
226         return nrad.get( layern );
227     }
228 
229     public double getDe( int layern )
230     {
231         return de.get( layern );
232     }
233 }