1
2
3
4
5
6
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
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
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.;
75 double minE = .05;
76 _fcc = new FixedConeClusterer(radius, seed, minE, FixedConeDistanceMetric.DPHIDTHETA);
77
78 _ecalLayering = _cond.getDoubleArray("ECalLayering");
79 _useFirstLayer = _cond.getDouble("IsFirstEmLayerSampling")==1.;
80
81
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
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
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
121
122
123 List<CalorimeterHit> hits = c.getCalorimeterHits();
124 for (CalorimeterHit hit : hits)
125 {
126 Subdetector det = hit.getSubdetector();
127 String detName = det.getName();
128
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
143 else
144 {
145 caltype = 3;
146 }
147
148 String name = type + "_" +(isEM ? "em"+caltype : "had") + (isEndcap ? "e" : "b");
149
150 SpacePoint p = new CartesianPoint(hit.getPosition());
151 double hitTheta = p.theta();
152 double normalTheta = hitTheta;
153
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
182
183 e += hit.getRawEnergy()/correctionFactor;
184 }
185 return e;
186 }
187 }