11 #include <pxd/modules/pxdPerformanceCollector/PXDPerformanceCollectorModule.h>
13 #include <framework/datastore/RelationArray.h>
15 #include <vxd/geometry/GeoCache.h>
16 #include <pxd/geometry/SensorInfo.h>
17 #include <pxd/reconstruction/PXDGainCalibrator.h>
24 #include <boost/format.hpp>
41 , m_pxd2TrackEvent(), m_signal(0), m_estimated(0.0), m_run(0), m_exp(0)
44 setDescription(
"Calibration collector module for CDST data.");
45 setPropertyFlags(c_ParallelProcessingCertified);
47 addParam(
"minPt", m_minPt,
"Minimum pt cut",
float(1.0));
48 addParam(
"minClusterCharge", m_minClusterCharge,
"Minimum cluster charge cut",
int(0));
49 addParam(
"minClusterSize", m_minClusterSize,
"Minimum cluster size cut ",
int(2));
50 addParam(
"maxClusterSize", m_maxClusterSize,
"Maximum cluster size cut ",
int(6));
51 addParam(
"nBinsU", m_nBinsU,
"Number of gain corrections per sensor along u side",
int(4));
52 addParam(
"nBinsV", m_nBinsV,
"Number of gain corrections per sensor along v side",
int(6));
53 addParam(
"gainPayloadName", m_gainName,
"Payload name for Gain to be read from DB",
string(
""));
54 addParam(
"fillChargeRatioHistogram", m_fillChargeRatioHistogram,
55 "Flag to fill Ratio (cluster charge to the expected MPV) histograms",
bool(
true));
56 addParam(
"fillChargeTree", m_fillChargeTree,
"Flag to fill cluster charge with the estimated MPV to TTree",
bool(
false));
57 addParam(
"fillEventTree", m_fillEventTree,
"Flag to fill event tree for validation",
bool(
false));
60 addParam(
"minPt4Eff", m_minPt4Eff,
"Minimum pt cut for efficiency validation",
float(2.0));
61 addParam(
"maxAbsVx", m_maxAbsVx,
"Minimum abs(Vx) cut in cm for efficiency validation",
float(0.03));
62 addParam(
"maxAbsVy", m_maxAbsVy,
"Minimum abs(Vy) cut in cm for efficiency validation",
float(0.03));
63 addParam(
"maxAbsVz", m_maxAbsVz,
"Minimum abs(Vz) cut in cm for efficiency validation",
float(0.155));
65 addParam(
"minPt4Res", m_minPt4Res,
"Minimum pt cut for resolution validation",
float(1.0));
66 addParam(
"minSVDHits", m_minSVDHits,
"Minimum number of SVD hits foor resolution validation",
int(8));
67 addParam(
"minCDCHits", m_minCDCHits,
"Minimum number of CDC hits foor resolution validation",
int(21));
68 addParam(
"maxAbsLambda", m_maxAbsLambda,
"Maximum absolute dip angle (lambda)",
float(0.5));
69 addParam(
"minPBetaSinTheta3o2", m_minPBetaSinTheta3o2,
"Minimum p*Beta*sin(theta_0)^{3/2}",
float(2));
70 addParam(
"maxAbsZ0", m_maxAbsZ0,
"Maximum abs(z0)",
float(1));
71 addParam(
"maxAbsD0", m_maxAbsD0,
"Maximum abs(d0)",
float(0.3));
76 void PXDPerformanceCollectorModule::prepare()
78 m_pxd2TrackEvents.isRequired(m_store2TrackEventsName);
81 B2WARNING(
"Number of bins along u side incremented from 0->1");
86 B2WARNING(
"Number of bins along v side incremented from 0->1");
90 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
91 int nPXDSensors = gTools->getNumberOfPXDSensors();
97 auto hPXDClusterCounter =
new TH1I(
"hPXDClusterCounter",
"Number of clusters found in data sample",
98 m_nBinsU * m_nBinsV * nPXDSensors, 0,
99 m_nBinsU * m_nBinsV * nPXDSensors);
100 hPXDClusterCounter->GetXaxis()->SetTitle(
"bin id");
101 hPXDClusterCounter->GetYaxis()->SetTitle(
"Number of clusters");
102 auto hPXDClusterChargeRatio =
new TH2F(
"hPXDClusterChargeRatio",
"Charge ratio of clusters found in data sample",
103 m_nBinsU * m_nBinsV * nPXDSensors, 0,
104 m_nBinsU * m_nBinsV * nPXDSensors,
106 hPXDClusterChargeRatio->GetXaxis()->SetTitle(
"bin id");
107 hPXDClusterChargeRatio->GetYaxis()->SetTitle(
"Cluster charge ratio (relative to expected MPV)");
118 for (
int iSensor = 0; iSensor < nPXDSensors; iSensor++) {
119 for (
int uBin = 0; uBin < m_nBinsU; uBin++) {
120 for (
int vBin = 0; vBin < m_nBinsV; vBin++) {
121 VxdID id = gTools->getSensorIDFromPXDIndex(iSensor);
122 string sensorDescr = id;
123 hPXDClusterCounter->GetXaxis()->SetBinLabel(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin + 1,
124 str(format(
"%1%_%2%_%3%") % sensorDescr % uBin % vBin).c_str());
125 if (m_fillChargeRatioHistogram)
126 hPXDClusterChargeRatio->GetXaxis()->SetBinLabel(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin + 1,
127 str(format(
"%1%_%2%_%3%") % sensorDescr % uBin % vBin).c_str());
136 registerObject<TH1I>(
"PXDClusterCounter", hPXDClusterCounter);
137 if (m_fillChargeRatioHistogram)
138 registerObject<TH2F>(
"PXDClusterChargeRatio", hPXDClusterChargeRatio);
143 auto hPXDTrackClusterCounter = (TH1I*)hPXDClusterCounter->Clone(
"hPXDTrackClusterCounter");
144 hPXDTrackClusterCounter->SetTitle(
"Number of track clusters");
145 hPXDTrackClusterCounter->GetYaxis()->SetTitle(
"Number of track clusters");
146 registerObject<TH1I>(
"PXDTrackClusterCounter", hPXDTrackClusterCounter);
151 auto hPXDTrackPointCounter = (TH1I*)hPXDClusterCounter->Clone(
"hPXDTrackPointCounter");
152 hPXDTrackPointCounter->SetTitle(
"Number of track points");
153 hPXDTrackPointCounter->GetYaxis()->SetTitle(
"Number of track points");
154 registerObject<TH1I>(
"PXDTrackPointCounter", hPXDTrackPointCounter);
160 if (m_fillChargeTree)
161 for (
int iSensor = 0; iSensor < nPXDSensors; iSensor++) {
162 for (
int uBin = 0; uBin < m_nBinsU; uBin++) {
163 for (
int vBin = 0; vBin < m_nBinsV; vBin++) {
164 VxdID id = gTools->getSensorIDFromPXDIndex(iSensor);
166 auto ladderNumber =
id.getLadderNumber();
167 auto sensorNumber =
id.getSensorNumber();
168 string treename = str(format(
"tree_%1%_%2%_%3%_%4%_%5%") % layerNumber % ladderNumber % sensorNumber % uBin % vBin);
169 auto tree =
new TTree(treename.c_str(), treename.c_str());
170 tree->Branch<
int>(
"signal", &m_signal);
171 tree->Branch<
float>(
"estimated", &m_estimated);
172 registerObject<TTree>(treename, tree);
182 auto hTotalHitsLayer1 =
new TH2F(
"hTotalHitsLayer1",
"Total number of hits from layer 1;#phi;z [cm]", 730, -M_PI, M_PI, 400,
184 auto hPassedHitsLayer1 =
new TH2F(
"hPassedHitsLayer1",
"Passed number of hits from layer 1;#phi;z [cm]", 730, -M_PI, M_PI, 400,
186 auto hTotalHitsLayer2 =
new TH2F(
"hTotalHitsLayer2",
"Total number of hits from layer 2;#phi;z [cm]", 128, 1.4, 2.5, 400,
188 auto hPassedHitsLayer2 =
new TH2F(
"hPassedHitsLayer2",
"Passed number of hits from layer 2;#phi;z [cm]", 128, 1.4, 2.5, 400,
190 registerObject<TH2F>(
"hTotalHitsLayer1", hTotalHitsLayer1);
191 registerObject<TH2F>(
"hPassedHitsLayer1", hPassedHitsLayer1);
192 registerObject<TH2F>(
"hTotalHitsLayer2", hTotalHitsLayer2);
193 registerObject<TH2F>(
"hPassedHitsLayer2", hPassedHitsLayer2);
196 auto treeD0Z0 =
new TTree(
"tree_d0z0",
"TTree of corrected d0 and z0");
197 treeD0Z0->Branch<
float>(
"d0", &m_deltaD0oSqrt2);
198 treeD0Z0->Branch<
float>(
"z0", &m_deltaZ0oSqrt2);
199 registerObject<TTree>(
"tree_d0z0", treeD0Z0);
202 auto dbtree =
new TTree(
"dbtree",
"dbtree");
203 dbtree->Branch<
int>(
"run", &m_run);
204 dbtree->Branch<
int>(
"exp", &m_exp);
206 registerObject<TTree>(
"dbtree", dbtree);
208 if (m_fillEventTree) {
209 auto tree =
new TTree(
"pxd",
"PXD 2-track events");
210 tree->Branch<
PXD2TrackEvent>(
"PXD2TrackEvent", &m_pxd2TrackEvent, 8000, 1);
211 registerObject<TTree>(
"pxd", tree);
215 void PXDPerformanceCollectorModule::startRun()
217 m_run = m_evtMetaData->getRun();
218 m_exp = m_evtMetaData->getExperiment();
219 if (m_gainName.length()) {
221 m_gainMap = *gainMap;
225 getObjectPtr<TTree>(
"dbtree")->Fill();
228 void PXDPerformanceCollectorModule::collect()
231 if (!m_pxd2TrackEvents)
return;
235 auto ip = beamSpotDB->getIPPosition();
238 for (
auto& pxd2TrackEvent : m_pxd2TrackEvents) {
239 m_selectedRes =
true;
240 m_selectedEff =
true;
242 auto vertex = pxd2TrackEvent.getVertex();
244 if (fabs(vertex.X()) > m_maxAbsVx ||
245 fabs(vertex.Y()) > m_maxAbsVy ||
246 fabs(vertex.Z()) > m_maxAbsVz)
247 m_selectedEff =
false;
250 collectFromTrack(pxd2TrackEvent.getTrackP());
251 collectFromTrack(pxd2TrackEvent.getTrackM());
254 collectDeltaIP(pxd2TrackEvent);
256 if (m_fillEventTree) {
257 m_pxd2TrackEvent = pxd2TrackEvent;
258 getObjectPtr<TTree>(
"pxd")->Fill();
264 void PXDPerformanceCollectorModule::collectDeltaIP(
const PXD2TrackEvent& event)
266 if (!m_selectedRes)
return;
267 auto d0p_1 =
event.getTrackP().d0p;
268 auto d0p_2 =
event.getTrackM().d0p;
269 auto z0p_1 =
event.getTrackP().z0p;
270 auto z0p_2 =
event.getTrackM().z0p;
271 m_deltaD0oSqrt2 = (d0p_1 + d0p_2) / sqrt(2.);
272 m_deltaZ0oSqrt2 = (z0p_1 - z0p_2) / sqrt(2.);
275 getObjectPtr<TTree>(
"tree_d0z0")->Fill();
278 void PXDPerformanceCollectorModule::collectFromTrack(
const PXD2TrackEvent::baseType& track)
280 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
281 bool selected4Gain =
true;
282 bool selected4Eff =
true;
284 if (track.pt < m_minPt) selected4Gain =
false;
285 if (track.pt < m_minPt4Eff) selected4Eff =
false;
288 if (track.pt < m_minPt4Res) m_selectedRes =
false;
289 if (track.nPXDHits < 1 || track.nCDCHits < m_minCDCHits || track.nSVDHits < m_minSVDHits)
290 m_selectedRes =
false;
291 if (fabs(track.d0p) > m_maxAbsD0 || fabs(track.z0p) > m_maxAbsZ0)
292 m_selectedRes =
false;
293 auto lambda0 = atan(track.tanLambda);
294 if (fabs(lambda0) > m_maxAbsLambda)
295 m_selectedRes =
false;
296 auto sinTheta0 = 1. / sqrt(1. + pow(track.tanLambda, 2));
297 auto pBetaSinTheta3o2 = track.pt * 1.0 * sqrt(sinTheta0);
298 if (pBetaSinTheta3o2 < m_minPBetaSinTheta3o2)
299 m_selectedRes =
false;
301 for (
auto& trackCluster : track.trackClusters) {
302 bool selectedCluster =
true;
303 auto cluster = trackCluster.cluster;
304 auto intersection = trackCluster.intersection;
305 auto usedInTrack = trackCluster.usedInTrack;
308 if (!usedInTrack || intersection.chargeMPV <= 0)
309 selectedCluster =
false;
312 if (cluster.charge < m_minClusterCharge || cluster.size < m_minClusterSize || cluster.size > m_maxClusterSize)
313 selectedCluster =
false;
315 if (cluster.pxdID <= 0) {
316 B2FATAL(
"Unexpected cluster module id : " << cluster.pxdID);
321 if (selected4Gain && selectedCluster) {
324 m_signal = cluster.charge;
325 m_estimated = intersection.chargeMPV;
331 auto iSensor = gTools->getPXDSensorIndex(sensorID);
335 auto uBin = PXD::PXDGainCalibrator::getInstance().getBinU(sensorID, uID, vID, m_nBinsU);
336 auto vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vID, m_nBinsV);
338 int binID = iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin;
341 getObjectPtr<TH1I>(
"PXDClusterCounter")->Fill(binID);
344 if (m_fillChargeTree) {
345 string treename = str(format(
"tree_%1%_%2%_%3%_%4%_%5%") % layerNumber % ladderNumber % sensorNumber % uBin % vBin);
346 getObjectPtr<TTree>(treename)->Fill();
350 if (m_fillChargeRatioHistogram) {
351 double ratio = m_signal / m_estimated;
352 auto axis = getObjectPtr<TH2F>(
"PXDClusterChargeRatio")->GetYaxis();
353 double maxY = axis->GetBinCenter(axis->GetNbins());
355 getObjectPtr<TH2F>(
"PXDClusterChargeRatio")->Fill(binID, TMath::Min(ratio, maxY));
360 if (m_selectedEff && selected4Eff) {
361 auto x = intersection.x;
362 auto y = intersection.y;
363 auto phi = atan2(y, x);
364 auto z = intersection.z;
372 auto iSensor = gTools->getPXDSensorIndex(sensorID);
373 auto uBin = PXD::PXDGainCalibrator::getInstance().getBinU(sensorID, uID, vID, m_nBinsU);
374 auto vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vID, m_nBinsV);
377 getObjectPtr<TH1I>(
"PXDTrackPointCounter")->Fill(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin);
379 getObjectPtr<TH1I>(
"PXDTrackClusterCounter")->Fill(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin);
382 if (cluster.pxdID < 2000) {
384 getObjectPtr<TH2F>(
"hTotalHitsLayer1")->Fill(phi, z);
386 getObjectPtr<TH2F>(
"hPassedHitsLayer1")->Fill(phi, z);
389 getObjectPtr<TH2F>(
"hTotalHitsLayer2")->Fill(phi, z);
391 getObjectPtr<TH2F>(
"hPassedHitsLayer2")->Fill(phi, z);