9 #include <pxd/modules/pxdPerformanceCollector/PXDPerformanceCollectorModule.h>
11 #include <framework/datastore/RelationArray.h>
13 #include <vxd/geometry/GeoCache.h>
14 #include <pxd/geometry/SensorInfo.h>
15 #include <pxd/reconstruction/PXDGainCalibrator.h>
22 #include <boost/format.hpp>
39 , m_selectedEff(true), m_selectedRes(true)
41 , m_deltaD0oSqrt2(0.0), m_deltaZ0oSqrt2(0.0)
42 , m_signal(0), m_estimated(0.0)
46 setDescription(
"Calibration collector module for CDST data.");
47 setPropertyFlags(c_ParallelProcessingCertified);
49 addParam(
"minPt", m_minPt,
"Minimum pt cut",
float(1.0));
50 addParam(
"minClusterCharge", m_minClusterCharge,
"Minimum cluster charge cut",
int(0));
51 addParam(
"minClusterSize", m_minClusterSize,
"Minimum cluster size cut ",
int(2));
52 addParam(
"maxClusterSize", m_maxClusterSize,
"Maximum cluster size cut ",
int(6));
53 addParam(
"nBinsU", m_nBinsU,
"Number of gain corrections per sensor along u side",
int(4));
54 addParam(
"nBinsV", m_nBinsV,
"Number of gain corrections per sensor along v side",
int(6));
55 addParam(
"gainPayloadName", m_gainName,
"Payload name for Gain to be read from DB",
string(
""));
56 addParam(
"fillChargeRatioHistogram", m_fillChargeRatioHistogram,
57 "Flag to fill Ratio (cluster charge to the expected MPV) histograms",
bool(
true));
58 addParam(
"fillChargeTree", m_fillChargeTree,
"Flag to fill cluster charge with the estimated MPV to TTree",
bool(
false));
59 addParam(
"fillEventTree", m_fillEventTree,
"Flag to fill event tree for validation",
bool(
false));
62 addParam(
"minPt4Eff", m_minPt4Eff,
"Minimum pt cut for efficiency validation",
float(2.0));
63 addParam(
"maxAbsVx", m_maxAbsVx,
"Minimum abs(Vx) cut in cm for efficiency validation",
float(0.03));
64 addParam(
"maxAbsVy", m_maxAbsVy,
"Minimum abs(Vy) cut in cm for efficiency validation",
float(0.03));
65 addParam(
"maxAbsVz", m_maxAbsVz,
"Minimum abs(Vz) cut in cm for efficiency validation",
float(0.155));
67 addParam(
"minPt4Res", m_minPt4Res,
"Minimum pt cut for resolution validation",
float(1.0));
68 addParam(
"minSVDHits", m_minSVDHits,
"Minimum number of SVD hits foor resolution validation",
int(8));
69 addParam(
"minCDCHits", m_minCDCHits,
"Minimum number of CDC hits foor resolution validation",
int(21));
70 addParam(
"maxAbsLambda", m_maxAbsLambda,
"Maximum absolute dip angle (lambda)",
float(0.5));
71 addParam(
"minPBetaSinTheta3o2", m_minPBetaSinTheta3o2,
"Minimum p*Beta*sin(theta_0)^{3/2}",
float(2));
72 addParam(
"maxAbsZ0", m_maxAbsZ0,
"Maximum abs(z0)",
float(1));
73 addParam(
"maxAbsD0", m_maxAbsD0,
"Maximum abs(d0)",
float(0.3));
78 void PXDPerformanceCollectorModule::prepare()
80 m_pxd2TrackEvents.isRequired(m_store2TrackEventsName);
83 B2WARNING(
"Number of bins along u side incremented from 0->1");
88 B2WARNING(
"Number of bins along v side incremented from 0->1");
92 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
93 int nPXDSensors = gTools->getNumberOfPXDSensors();
99 auto hPXDClusterCounter =
new TH1I(
"hPXDClusterCounter",
"Number of clusters found in data sample",
100 m_nBinsU * m_nBinsV * nPXDSensors, 0,
101 m_nBinsU * m_nBinsV * nPXDSensors);
102 hPXDClusterCounter->GetXaxis()->SetTitle(
"bin id");
103 hPXDClusterCounter->GetYaxis()->SetTitle(
"Number of clusters");
104 auto hPXDClusterChargeRatio =
new TH2F(
"hPXDClusterChargeRatio",
"Charge ratio of clusters found in data sample",
105 m_nBinsU * m_nBinsV * nPXDSensors, 0,
106 m_nBinsU * m_nBinsV * nPXDSensors,
108 hPXDClusterChargeRatio->GetXaxis()->SetTitle(
"bin id");
109 hPXDClusterChargeRatio->GetYaxis()->SetTitle(
"Cluster charge ratio (relative to expected MPV)");
120 for (
int iSensor = 0; iSensor < nPXDSensors; iSensor++) {
121 for (
int uBin = 0; uBin < m_nBinsU; uBin++) {
122 for (
int vBin = 0; vBin < m_nBinsV; vBin++) {
123 VxdID id = gTools->getSensorIDFromPXDIndex(iSensor);
124 string sensorDescr = id;
125 hPXDClusterCounter->GetXaxis()->SetBinLabel(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin + 1,
126 str(format(
"%1%_%2%_%3%") % sensorDescr % uBin % vBin).c_str());
127 if (m_fillChargeRatioHistogram)
128 hPXDClusterChargeRatio->GetXaxis()->SetBinLabel(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin + 1,
129 str(format(
"%1%_%2%_%3%") % sensorDescr % uBin % vBin).c_str());
138 registerObject<TH1I>(
"PXDClusterCounter", hPXDClusterCounter);
139 if (m_fillChargeRatioHistogram)
140 registerObject<TH2F>(
"PXDClusterChargeRatio", hPXDClusterChargeRatio);
145 auto hPXDTrackClusterCounter = (TH1I*)hPXDClusterCounter->Clone(
"hPXDTrackClusterCounter");
146 hPXDTrackClusterCounter->SetTitle(
"Number of track clusters");
147 hPXDTrackClusterCounter->GetYaxis()->SetTitle(
"Number of track clusters");
148 registerObject<TH1I>(
"PXDTrackClusterCounter", hPXDTrackClusterCounter);
153 auto hPXDTrackPointCounter = (TH1I*)hPXDClusterCounter->Clone(
"hPXDTrackPointCounter");
154 hPXDTrackPointCounter->SetTitle(
"Number of track points");
155 hPXDTrackPointCounter->GetYaxis()->SetTitle(
"Number of track points");
156 registerObject<TH1I>(
"PXDTrackPointCounter", hPXDTrackPointCounter);
162 if (m_fillChargeTree)
163 for (
int iSensor = 0; iSensor < nPXDSensors; iSensor++) {
164 for (
int uBin = 0; uBin < m_nBinsU; uBin++) {
165 for (
int vBin = 0; vBin < m_nBinsV; vBin++) {
166 VxdID id = gTools->getSensorIDFromPXDIndex(iSensor);
168 auto ladderNumber =
id.getLadderNumber();
169 auto sensorNumber =
id.getSensorNumber();
170 string treename = str(format(
"tree_%1%_%2%_%3%_%4%_%5%") % layerNumber % ladderNumber % sensorNumber % uBin % vBin);
171 auto tree =
new TTree(treename.c_str(), treename.c_str());
172 tree->Branch<
int>(
"signal", &m_signal);
173 tree->Branch<
float>(
"estimated", &m_estimated);
174 registerObject<TTree>(treename, tree);
184 auto hTotalHitsLayer1 =
new TH2F(
"hTotalHitsLayer1",
"Total number of hits from layer 1;#phi;z [cm]", 730, -M_PI, M_PI, 400,
186 auto hPassedHitsLayer1 =
new TH2F(
"hPassedHitsLayer1",
"Passed number of hits from layer 1;#phi;z [cm]", 730, -M_PI, M_PI, 400,
188 auto hTotalHitsLayer2 =
new TH2F(
"hTotalHitsLayer2",
"Total number of hits from layer 2;#phi;z [cm]", 128, 1.4, 2.5, 400,
190 auto hPassedHitsLayer2 =
new TH2F(
"hPassedHitsLayer2",
"Passed number of hits from layer 2;#phi;z [cm]", 128, 1.4, 2.5, 400,
192 registerObject<TH2F>(
"hTotalHitsLayer1", hTotalHitsLayer1);
193 registerObject<TH2F>(
"hPassedHitsLayer1", hPassedHitsLayer1);
194 registerObject<TH2F>(
"hTotalHitsLayer2", hTotalHitsLayer2);
195 registerObject<TH2F>(
"hPassedHitsLayer2", hPassedHitsLayer2);
198 auto treeD0Z0 =
new TTree(
"tree_d0z0",
"TTree of corrected d0 and z0");
199 treeD0Z0->Branch<
float>(
"d0", &m_deltaD0oSqrt2);
200 treeD0Z0->Branch<
float>(
"z0", &m_deltaZ0oSqrt2);
201 registerObject<TTree>(
"tree_d0z0", treeD0Z0);
204 auto dbtree =
new TTree(
"dbtree",
"dbtree");
205 dbtree->Branch<
int>(
"run", &m_run);
206 dbtree->Branch<
int>(
"exp", &m_exp);
208 registerObject<TTree>(
"dbtree", dbtree);
210 if (m_fillEventTree) {
211 auto tree =
new TTree(
"pxd",
"PXD 2-track events");
212 tree->Branch<
PXD2TrackEvent>(
"PXD2TrackEvent", &m_pxd2TrackEvent, 8000, 1);
213 registerObject<TTree>(
"pxd", tree);
217 void PXDPerformanceCollectorModule::startRun()
219 m_run = m_evtMetaData->getRun();
220 m_exp = m_evtMetaData->getExperiment();
221 if (m_gainName.length()) {
223 m_gainMap = *gainMap;
227 getObjectPtr<TTree>(
"dbtree")->Fill();
230 void PXDPerformanceCollectorModule::collect()
233 if (!m_pxd2TrackEvents)
return;
237 auto ip = beamSpotDB->getIPPosition();
240 for (
auto& pxd2TrackEvent : m_pxd2TrackEvents) {
241 m_selectedRes =
true;
242 m_selectedEff =
true;
244 auto vertex = pxd2TrackEvent.getVertex();
246 if (fabs(vertex.X()) > m_maxAbsVx ||
247 fabs(vertex.Y()) > m_maxAbsVy ||
248 fabs(vertex.Z()) > m_maxAbsVz)
249 m_selectedEff =
false;
252 collectFromTrack(pxd2TrackEvent.getTrackP());
253 collectFromTrack(pxd2TrackEvent.getTrackM());
256 collectDeltaIP(pxd2TrackEvent);
258 if (m_fillEventTree) {
259 m_pxd2TrackEvent = pxd2TrackEvent;
260 getObjectPtr<TTree>(
"pxd")->Fill();
268 if (!m_selectedRes)
return;
269 auto d0p_1 =
event.getTrackP().d0p;
270 auto d0p_2 =
event.getTrackM().d0p;
271 auto z0p_1 =
event.getTrackP().z0p;
272 auto z0p_2 =
event.getTrackM().z0p;
273 m_deltaD0oSqrt2 = (d0p_1 + d0p_2) / sqrt(2.);
274 m_deltaZ0oSqrt2 = (z0p_1 - z0p_2) / sqrt(2.);
277 getObjectPtr<TTree>(
"tree_d0z0")->Fill();
282 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
283 bool selected4Gain =
true;
284 bool selected4Eff =
true;
286 if (track.pt < m_minPt) selected4Gain =
false;
287 if (track.pt < m_minPt4Eff) selected4Eff =
false;
290 if (track.pt < m_minPt4Res) m_selectedRes =
false;
291 if (track.nPXDHits < 1 || track.nCDCHits < m_minCDCHits || track.nSVDHits < m_minSVDHits)
292 m_selectedRes =
false;
293 if (fabs(track.d0p) > m_maxAbsD0 || fabs(track.z0p) > m_maxAbsZ0)
294 m_selectedRes =
false;
295 auto lambda0 = atan(track.tanLambda);
296 if (fabs(lambda0) > m_maxAbsLambda)
297 m_selectedRes =
false;
298 auto sinTheta0 = 1. / sqrt(1. + pow(track.tanLambda, 2));
299 auto pBetaSinTheta3o2 = track.pt * 1.0 * sqrt(sinTheta0);
300 if (pBetaSinTheta3o2 < m_minPBetaSinTheta3o2)
301 m_selectedRes =
false;
303 for (
auto& trackCluster : track.trackClusters) {
304 bool selectedCluster =
true;
305 auto cluster = trackCluster.cluster;
306 auto intersection = trackCluster.intersection;
307 auto usedInTrack = trackCluster.usedInTrack;
310 if (!usedInTrack || intersection.chargeMPV <= 0)
311 selectedCluster =
false;
314 if (cluster.charge < m_minClusterCharge || cluster.size < m_minClusterSize || cluster.size > m_maxClusterSize)
315 selectedCluster =
false;
317 if (cluster.pxdID <= 0) {
318 B2FATAL(
"Unexpected cluster module id : " << cluster.pxdID);
323 if (selected4Gain && selectedCluster) {
326 m_signal = cluster.charge;
327 m_estimated = intersection.chargeMPV;
333 auto iSensor = gTools->getPXDSensorIndex(sensorID);
337 auto uBin = PXD::PXDGainCalibrator::getInstance().getBinU(sensorID, uID, vID, m_nBinsU);
338 auto vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vID, m_nBinsV);
340 int binID = iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin;
343 getObjectPtr<TH1I>(
"PXDClusterCounter")->Fill(binID);
346 if (m_fillChargeTree) {
347 string treename = str(format(
"tree_%1%_%2%_%3%_%4%_%5%") % layerNumber % ladderNumber % sensorNumber % uBin % vBin);
348 getObjectPtr<TTree>(treename)->Fill();
352 if (m_fillChargeRatioHistogram) {
353 double ratio = m_signal / m_estimated;
354 auto axis = getObjectPtr<TH2F>(
"PXDClusterChargeRatio")->GetYaxis();
355 double maxY = axis->GetBinCenter(axis->GetNbins());
357 getObjectPtr<TH2F>(
"PXDClusterChargeRatio")->Fill(binID, TMath::Min(ratio, maxY));
362 if (m_selectedEff && selected4Eff) {
363 auto x = intersection.x;
364 auto y = intersection.y;
365 auto phi = atan2(y, x);
366 auto z = intersection.z;
374 auto iSensor = gTools->getPXDSensorIndex(sensorID);
375 auto uBin = PXD::PXDGainCalibrator::getInstance().getBinU(sensorID, uID, vID, m_nBinsU);
376 auto vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vID, m_nBinsV);
379 getObjectPtr<TH1I>(
"PXDTrackPointCounter")->Fill(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin);
381 getObjectPtr<TH1I>(
"PXDTrackClusterCounter")->Fill(iSensor * m_nBinsU * m_nBinsV + uBin * m_nBinsV + vBin);
384 if (cluster.pxdID < 2000) {
386 getObjectPtr<TH2F>(
"hTotalHitsLayer1")->Fill(phi, z);
388 getObjectPtr<TH2F>(
"hPassedHitsLayer1")->Fill(phi, z);
391 getObjectPtr<TH2F>(
"hTotalHitsLayer2")->Fill(phi, z);
393 getObjectPtr<TH2F>(
"hPassedHitsLayer2")->Fill(phi, z);
Calibration collector module base class.
Class for accessing objects in the database.
Class PXD2TrackEvent: Event data container for performance and calibration studies.
The payload class for PXD gain corrections.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
TVector3 pointToLocal(const TVector3 &global, bool reco=false) const
Convert a point from global to local coordinates.
int getVCellID(double v, bool clamp=false) const
Return the corresponding pixel/strip ID of a given v coordinate.
int getUCellID(double u, double v=0, bool clamp=false) const
Return the corresponding pixel/strip ID of a given u coordinate.
Class to uniquely identify a any structure of the PXD and SVD.
baseType getSensorNumber() const
Get the sensor id.
baseType getLadderNumber() const
Get the ladder id.
baseType getLayerNumber() const
Get the layer id.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
VxdID getVxdIDFromPXDModuleID(const unsigned short &id)
Helper function to get VxdID from DHE id like module iid.
Abstract base class for different kinds of events.