View Javadoc

1   /*
2    * ClusterCalibrationAnalysisDriver.java
3    *
4    * Created on May 22, 2008, 9:37 AM
5    *
6    * $Id: ClusterCalibrationAnalysisDriver.java,v 1.1 2008/05/27 18:12:21 ngraf Exp $
7    */
8   
9   package org.lcsim.cal.calib;
10  
11  import hep.aida.ITree;
12  import java.util.HashMap;
13  import java.util.List;
14  import java.util.Map;
15  import org.lcsim.conditions.ConditionsManager;
16  import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
17  import org.lcsim.conditions.ConditionsSet;
18  import org.lcsim.event.CalorimeterHit;
19  import org.lcsim.event.Cluster;
20  import org.lcsim.event.EventHeader;
21  import org.lcsim.geometry.IDDecoder;
22  import org.lcsim.geometry.Subdetector;
23  import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer;
24  import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer.FixedConeDistanceMetric;
25  import org.lcsim.spacegeom.CartesianPoint;
26  import org.lcsim.spacegeom.SpacePoint;
27  import org.lcsim.util.Driver;
28  import org.lcsim.util.aida.AIDA;
29  
30  import static java.lang.Math.sin;
31  import static java.lang.Math.PI;
32  import static java.lang.Math.abs;
33  /**
34   *
35   * @author Norman Graf
36   */
37  public class ClusterCalibrationAnalysisDriver extends Driver
38  {
39      private ConditionsSet _cond;
40      private FixedConeClusterer _fcc;
41      private CollectionManager _collectionmanager = CollectionManager.defaultInstance();
42      
43      
44      private AIDA aida = AIDA.defaultInstance();
45      private ITree _tree;
46      
47      private double[] _ecalLayering;
48      boolean _useFirstLayer;
49      
50      Map<String, Double> _fitParameters = new HashMap<String, Double>();
51      
52      private boolean _initialized;
53      /** Creates a new instance of ClusterCalibrationAnalysisDriver */
54      public ClusterCalibrationAnalysisDriver()
55      {
56          _tree = aida.tree();
57      }
58      
59      protected void process(EventHeader event)
60      {
61          if(!_initialized)
62          {
63              ConditionsManager mgr = ConditionsManager.defaultInstance();
64              try
65              {
66                  _cond = mgr.getConditions("CalorimeterCalibration");
67              }
68              catch(ConditionsSetNotFoundException e)
69              {
70                  System.out.println("ConditionSet CalorimeterCalibration not found for detector "+mgr.getDetector());
71                  System.out.println("Please check that this properties file exists for this detector ");
72              }
73              double radius = .5;
74              double seed = 0.;//.1;
75              double minE = .05; //.25;
76              _fcc = new FixedConeClusterer(radius, seed, minE, FixedConeDistanceMetric.DPHIDTHETA);
77              
78              _ecalLayering = _cond.getDoubleArray("ECalLayering");
79              _useFirstLayer = _cond.getDouble("IsFirstEmLayerSampling")==1.;
80              
81              // photons
82              String photonFitParametersList = _cond.getString("PhotonFitParameters");
83              String[]  photonFitParameters = photonFitParametersList.split(",\\s");
84              for(int i=0; i<photonFitParameters.length; ++i)
85              {
86                  _fitParameters.put(photonFitParameters[i], _cond.getDouble(photonFitParameters[i]));
87              }
88              // neutral hadrons
89              String hadronFitParametersList = _cond.getString("NeutralHadronFitParameters");
90              String[]  hadronFitParameters = hadronFitParametersList.split(",\\s");
91              for(int i=0; i<hadronFitParameters.length; ++i)
92              {
93                  _fitParameters.put(hadronFitParameters[i], _cond.getDouble(hadronFitParameters[i]));
94              }
95              
96              _initialized = true;
97          }
98          
99          String processedHitsName = _cond.getString("ProcessedHitsCollectionName");
100         List<CalorimeterHit> hitsToCluster = _collectionmanager.getList(processedHitsName);
101         // cluster the hits
102         List<Cluster> clusters = _fcc.createClusters(hitsToCluster);
103         String type = "gamma";
104         for(Cluster c : clusters)
105         {
106             aida.cloud1D("uncorrected cluster energy for all clusters").fill(c.getEnergy());
107             double e = correctClusterEnergy(c, type);
108             aida.cloud1D("corrected cluster energy for all clusters").fill(e);
109             SpacePoint p = new CartesianPoint(c.getPosition());
110             double clusterTheta = p.theta();
111             aida.cloud2D("uncorrected cluster energy for all clusters vs theta").fill(clusterTheta, c.getEnergy());
112             aida.cloud2D("corrected cluster energy for all clusters vs theta").fill(clusterTheta, e);
113             aida.cloud2D("raw-corrected cluster energy for all clusters vs theta").fill(clusterTheta, c.getEnergy()-e);         
114         }        
115     }
116     
117     private double correctClusterEnergy(Cluster c, String type)
118     {
119         double e = 0.;
120         // brute force for the time being
121         // in the future we will either move this to the sampling fraction corrections
122         // or use the cluster direction for calculating the angle effect.
123         List<CalorimeterHit> hits = c.getCalorimeterHits();
124         for (CalorimeterHit hit : hits)
125         {
126             Subdetector det = hit.getSubdetector();
127             String detName = det.getName();
128 //            System.out.println(detName);
129             boolean isEM = detName.startsWith("EM");
130             boolean isEndcap = det.isEndcap();
131             IDDecoder decoder = hit.getIDDecoder();
132             decoder.setID(hit.getCellID());
133             int layer = decoder.getLayer();
134             int caltype = 0;
135             if(isEM)
136             {
137             for(int i=1; i<_ecalLayering.length+1; ++i)
138             {
139                 if(layer >= _ecalLayering[i-1]) caltype = i-1;
140             }
141             }
142             //TODO change this when had cal layering changes...
143             else
144             {
145                 caltype  = 3;
146             }
147 //            System.out.println("layer= "+layer+" caltype= "+caltype);
148             String name = type + "_" +(isEM ? "em"+caltype : "had") + (isEndcap ? "e" : "b");
149 //            System.out.println("fit parameter name "+name);
150             SpacePoint p = new CartesianPoint(hit.getPosition());
151             double hitTheta = p.theta();
152             double normalTheta = hitTheta;
153             // now calculate normal to the sampling plane
154             if(isEndcap)
155             {
156                 normalTheta -= PI/2.;
157                 normalTheta = abs(normalTheta);
158             }
159             else
160             {
161                 normalTheta -= PI;
162             }
163             double a = 0.;
164             double b = 0.;
165             if(caltype==0 && !_useFirstLayer)
166             {
167                 a = 0.;
168                 b = 1.;
169             }
170             else
171             {
172                 a = _fitParameters.get(name+"_0");
173                 b = _fitParameters.get(name+"_1");
174             }
175             
176             double correctionFactor = a + b*sin(normalTheta);
177             aida.cloud2D(name+" "+layer+"hit Theta vs correction factor ").fill(hitTheta, correctionFactor);
178             aida.cloud2D(name+" hit Theta vs correction factor ").fill(hitTheta, correctionFactor);
179             if(isEM) aida.cloud2D("EM layer vs caltype").fill(layer, caltype);
180             
181             // now apply the correction
182             
183             e += hit.getRawEnergy()/correctionFactor;
184         }
185         return e;
186     }
187 }