13 #include "pxd/modules/pxdDQM/PXDDQMClustersModule.h"
15 #include <framework/core/HistoModule.h>
16 #include <framework/gearbox/Unit.h>
17 #include <framework/datastore/StoreObjPtr.h>
18 #include <framework/datastore/StoreArray.h>
19 #include <framework/datastore/RelationArray.h>
21 #include <pxd/dataobjects/PXDDigit.h>
22 #include <pxd/dataobjects/PXDCluster.h>
23 #include <pxd/geometry/SensorInfo.h>
25 #include <vxd/geometry/GeoCache.h>
26 #include <vxd/geometry/SensorInfoBase.h>
27 #include <vxd/geometry/GeoTools.h>
28 #include <pxd/unpacking/PXDMappingLookup.h>
29 #include <pxd/reconstruction/PXDGainCalibrator.h>
31 #include <boost/format.hpp>
33 #include "TDirectory.h"
53 setDescription(
"PXD DQM clusters module "
54 "Recommended Number of events for monitorin is 40 kEvents or more to fill all histograms "
57 setPropertyFlags(c_ParallelProcessingCertified);
58 addParam(
"CutPXDCharge", m_CutPXDCharge,
59 "cut on pixel or cluster charge for accepting to hitmap histogram, default = 0 ", m_CutPXDCharge);
60 addParam(
"histogramDirectoryName", m_histogramDirectoryName,
"Name of the directory where histograms will be placed",
61 std::string(
"PXDDQMClusters"));
71 void PXDDQMClustersModule::defineHisto()
73 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
74 if (gTools->getNumberOfLayers() == 0) {
75 B2FATAL(
"Missing geometry for VXD, check steering file.");
77 if (gTools->getNumberOfPXDLayers() == 0) {
78 B2WARNING(
"Missing geometry for PXD, PXD-DQM is skiped.");
83 TDirectory* oldDir = gDirectory;
84 if (m_histogramDirectoryName !=
"") {
85 oldDir->mkdir(m_histogramDirectoryName.c_str());
86 oldDir->cd(m_histogramDirectoryName.c_str());
90 int nPXDSensors = gTools->getNumberOfPXDSensors();
91 int nPXDChips = gTools->getTotalPXDChips();
94 m_hitMapCounts =
new TH1D(
"DQM_PXD_PixelHitmapCounts",
"DQM PXD Integrated number of fired pixels per sensor",
95 nPXDSensors, 0, nPXDSensors);
96 m_hitMapCounts->GetXaxis()->SetTitle(
"Sensor ID");
97 m_hitMapCounts->GetYaxis()->SetTitle(
"counts");
98 m_hitMapClCounts =
new TH1D(
"DQM_PXD_ClusterHitmapCounts",
"DQM PXD Integrated number of clusters per sensor",
99 nPXDSensors, 0, nPXDSensors);
100 m_hitMapClCounts->GetXaxis()->SetTitle(
"Sensor ID");
101 m_hitMapClCounts->GetYaxis()->SetTitle(
"counts");
103 m_hitMapCountsChip =
new TH1D(
"DQM_PXD_PixelHitmapCountsChip",
"DQM PXD Integrated number of fired pixels per chip",
104 nPXDChips, 0, nPXDChips);
105 m_hitMapCountsChip->GetXaxis()->SetTitle(
"Sensor ID");
106 m_hitMapCountsChip->GetYaxis()->SetTitle(
"counts");
107 m_hitMapClCountsChip =
new TH1D(
"DQM_PXD_ClusterHitmapCountsChip",
"DQM PXD Integrated number of clusters per chip",
108 nPXDChips, 0, nPXDChips);
109 m_hitMapClCountsChip->GetXaxis()->SetTitle(
"Sensor ID");
110 m_hitMapClCountsChip->GetYaxis()->SetTitle(
"counts");
111 for (
int i = 0; i < nPXDChips; i++) {
112 VxdID id = gTools->getChipIDFromPXDIndex(i);
114 int iLadder =
id.getLadderNumber();
115 int iSensor =
id.getSensorNumber();
116 int iChip = gTools->getPXDChipNumber(
id);
117 int IsU = gTools->isPXDSideU(
id);
118 TString AxisTicks = Form(
"%i_%i_%i_u%iDCD", iLayer, iLadder, iSensor, iChip);
120 AxisTicks = Form(
"%i_%i_%i_v%iSWB", iLayer, iLadder, iSensor, iChip);
121 m_hitMapCountsChip->GetXaxis()->SetBinLabel(i + 1, AxisTicks.Data());
122 m_hitMapClCountsChip->GetXaxis()->SetBinLabel(i + 1, AxisTicks.Data());
125 for (
int i = 0; i < nPXDSensors; i++) {
126 VxdID id = gTools->getSensorIDFromPXDIndex(i);
128 int iLadder =
id.getLadderNumber();
129 int iSensor =
id.getSensorNumber();
130 TString AxisTicks = Form(
"%i_%i_%i", iLayer, iLadder, iSensor);
131 m_hitMapCounts->GetXaxis()->SetBinLabel(i + 1, AxisTicks.Data());
132 m_hitMapClCounts->GetXaxis()->SetBinLabel(i + 1, AxisTicks.Data());
135 m_fired =
new TH1F*[nPXDSensors];
136 m_clusters =
new TH1F*[nPXDSensors];
137 m_startRow =
new TH1F*[nPXDSensors];
138 m_chargStartRow =
new TH1F*[nPXDSensors];
139 m_startRowCount =
new TH1F*[nPXDSensors];
140 m_clusterCharge =
new TH1F*[nPXDSensors];
141 m_clusterEnergy =
new TH1F*[nPXDSensors];
142 m_pixelSignal =
new TH1F*[nPXDSensors];
143 m_clusterSizeU =
new TH1F*[nPXDSensors];
144 m_clusterSizeV =
new TH1F*[nPXDSensors];
145 m_clusterSizeUV =
new TH1F*[nPXDSensors];
147 m_hitMapU =
new TH1F*[nPXDSensors];
148 m_hitMapV =
new TH1F*[nPXDSensors];
149 m_hitMap =
new TH2F*[nPXDSensors];
150 m_hitMapUCl =
new TH1F*[nPXDSensors];
151 m_hitMapVCl =
new TH1F*[nPXDSensors];
152 m_hitMapCl =
new TH2F*[nPXDSensors];
153 m_seed =
new TH1F*[nPXDSensors];
154 for (
int i = 0; i < nPXDSensors; i++) {
155 VxdID id = gTools->getSensorIDFromPXDIndex(i);
157 int iLadder =
id.getLadderNumber();
158 int iSensor =
id.getSensorNumber();
159 VxdID sensorID(iLayer, iLadder, iSensor);
161 string sensorDescr = str(format(
"%1%_%2%_%3%") % iLayer % iLadder % iSensor);
165 string name = str(format(
"DQM_PXD_%1%_Fired") % sensorDescr);
166 string title = str(format(
"DQM PXD Sensor %1% Fired pixels") % sensorDescr);
167 m_fired[i] =
nullptr;
168 m_fired[i] =
new TH1F(name.c_str(), title.c_str(), 50, 0, 50);
169 m_fired[i]->GetXaxis()->SetTitle(
"# of fired pixels");
170 m_fired[i]->GetYaxis()->SetTitle(
"counts");
174 name = str(format(
"DQM_PXD_%1%_Clusters") % sensorDescr);
175 title = str(format(
"DQM PXD Sensor %1% Number of clusters") % sensorDescr);
176 m_clusters[i] =
nullptr;
177 m_clusters[i] =
new TH1F(name.c_str(), title.c_str(), 20, 0, 20);
178 m_clusters[i]->GetXaxis()->SetTitle(
"# of clusters");
179 m_clusters[i]->GetYaxis()->SetTitle(
"counts");
183 name = str(format(
"DQM_PXD_%1%_StartRow") % sensorDescr);
184 title = str(format(
"DQM PXD Sensor %1% Start row distribution") % sensorDescr);
188 m_startRow[i] =
new TH1F(name.c_str(), title.c_str(), nPixels / 4, 0.0, nPixels);
189 m_startRow[i]->GetXaxis()->SetTitle(
"start row [pitch units]");
190 m_startRow[i]->GetYaxis()->SetTitle(
"count");
194 name = str(format(
"DQM_PXD_%1%_AverageSeedByStartRow") % sensorDescr);
195 title = str(format(
"DQM PXD Sensor %1% Average seed charge by distance from the start row") % sensorDescr);
196 m_chargStartRow[i] =
new TH1F(name.c_str(), title.c_str(), nPixels / 4, 0.0, nPixels);
197 m_chargStartRow[i]->GetXaxis()->SetTitle(
"distance from the start row [pitch units]");
198 m_chargStartRow[i]->GetYaxis()->SetTitle(
"average seed [ADU]");
199 name = str(format(
"DQM_PXD_%1%_SeedCountsByStartRow") % sensorDescr);
200 title = str(format(
"DQM PXD Sensor %1% Seed charge count by distance from the start row") % sensorDescr);
201 m_startRowCount[i] =
new TH1F(name.c_str(), title.c_str(), nPixels / 4, 0.0, nPixels);
202 m_startRowCount[i]->GetXaxis()->SetTitle(
"distance from the start row [pitch units]");
203 m_startRowCount[i]->GetYaxis()->SetTitle(
"count");
207 name = str(format(
"DQM_PXD_%1%_ClusterCharge") % sensorDescr);
208 title = str(format(
"DQM PXD Sensor %1% Cluster Charge") % sensorDescr);
209 m_clusterCharge[i] =
new TH1F(name.c_str(), title.c_str(), 256, 0, 256);
210 m_clusterCharge[i]->GetXaxis()->SetTitle(
"charge of clusters [ADU]");
211 m_clusterCharge[i]->GetYaxis()->SetTitle(
"counts");
215 name = str(format(
"DQM_PXD_%1%_ClusterEnergy") % sensorDescr);
216 title = str(format(
"DQM PXD Sensor %1% Cluster Energy") % sensorDescr);
217 m_clusterEnergy[i] =
new TH1F(name.c_str(), title.c_str(), 100, 0, 50);
218 m_clusterEnergy[i]->GetXaxis()->SetTitle(
"energy of clusters [keV]");
219 m_clusterEnergy[i]->GetYaxis()->SetTitle(
"counts");
223 name = str(format(
"DQM_PXD_%1%_PixelSignal") % sensorDescr);
224 title = str(format(
"DQM PXD Sensor %1% Pixel Signal") % sensorDescr);
225 m_pixelSignal[i] =
new TH1F(name.c_str(), title.c_str(), 256, 0, 256);
226 m_pixelSignal[i]->GetXaxis()->SetTitle(
"signal of pixels [ADU]");
227 m_pixelSignal[i]->GetYaxis()->SetTitle(
"counts");
231 name = str(format(
"DQM_PXD_%1%_ClusterSizeU") % sensorDescr);
232 title = str(format(
"DQM PXD Sensor %1% Cluster Size U") % sensorDescr);
233 m_clusterSizeU[i] =
new TH1F(name.c_str(), title.c_str(), 10, 0, 10);
234 m_clusterSizeU[i]->GetXaxis()->SetTitle(
"size of u clusters");
235 m_clusterSizeU[i]->GetYaxis()->SetTitle(
"counts");
239 name = str(format(
"DQM_PXD_%1%_ClusterSizeV") % sensorDescr);
240 title = str(format(
"DQM PXD Sensor %1% Cluster Size V") % sensorDescr);
241 m_clusterSizeV[i] =
new TH1F(name.c_str(), title.c_str(), 10, 0, 10);
242 m_clusterSizeV[i]->GetXaxis()->SetTitle(
"size of v clusters");
243 m_clusterSizeV[i]->GetYaxis()->SetTitle(
"counts");
247 name = str(format(
"DQM_PXD_%1%_ClusterSizeUV") % sensorDescr);
248 title = str(format(
"DQM PXD Sensor %1% Cluster Size U+V") % sensorDescr);
249 m_clusterSizeUV[i] =
new TH1F(name.c_str(), title.c_str(), 10, 0, 10);
250 m_clusterSizeUV[i]->GetXaxis()->SetTitle(
"size of u+v clusters");
251 m_clusterSizeUV[i]->GetYaxis()->SetTitle(
"counts");
257 name = str(format(
"PXD_%1%_PixelHitmapU") % sensorDescr);
258 title = str(format(
"PXD Sensor %1% Pixel Hitmap in U") % sensorDescr);
260 m_hitMapU[i] =
new TH1F(name.c_str(), title.c_str(), nPixels, 0, nPixels);
261 m_hitMapU[i]->GetXaxis()->SetTitle(
"u position [pitch units]");
262 m_hitMapU[i]->GetYaxis()->SetTitle(
"hits");
264 name = str(format(
"PXD_%1%_PixelHitmapV") % sensorDescr);
265 title = str(format(
"PXD Sensor %1% Pixel Hitmap in V") % sensorDescr);
267 m_hitMapV[i] =
new TH1F(name.c_str(), title.c_str(), nPixels, 0, nPixels);
268 m_hitMapV[i]->GetXaxis()->SetTitle(
"v position [pitch units]");
269 m_hitMapV[i]->GetYaxis()->SetTitle(
"hits");
271 name = str(format(
"PXD_%1%_PixelHitmap") % sensorDescr);
272 title = str(format(
"PXD Sensor %1% Pixel Hitmap") % sensorDescr);
275 m_hitMap[i] =
new TH2F(name.c_str(), title.c_str(), nPixels, 0, nPixels, nPixelsV, 0, nPixelsV);
276 m_hitMap[i]->GetXaxis()->SetTitle(
"u position [pitch units]");
277 m_hitMap[i]->GetYaxis()->SetTitle(
"v position [pitch units]");
278 m_hitMap[i]->GetZaxis()->SetTitle(
"hits");
284 name = str(format(
"PXD_%1%_HitmapClstU") % sensorDescr);
285 title = str(format(
"PXD Sensor %1% Hitmap Clusters in U") % sensorDescr);
287 m_hitMapUCl[i] =
new TH1F(name.c_str(), title.c_str(), nPixels, 0, nPixels);
288 m_hitMapUCl[i]->GetXaxis()->SetTitle(
"u position [pitch units]");
289 m_hitMapUCl[i]->GetYaxis()->SetTitle(
"hits");
291 name = str(format(
"PXD_%1%_HitmapClstV") % sensorDescr);
292 title = str(format(
"PXD Sensor %1% Hitmap Clusters in V") % sensorDescr);
294 m_hitMapVCl[i] =
new TH1F(name.c_str(), title.c_str(), nPixels, 0, nPixels);
295 m_hitMapVCl[i]->GetXaxis()->SetTitle(
"v position [pitch units]");
296 m_hitMapVCl[i]->GetYaxis()->SetTitle(
"hits");
298 name = str(format(
"PXD_%1%_HitmapClst") % sensorDescr);
299 title = str(format(
"PXD Sensor %1% Hitmap Clusters") % sensorDescr);
302 m_hitMapCl[i] =
new TH2F(name.c_str(), title.c_str(), nPixels, 0, nPixels, nPixelsV, 0, nPixelsV);
303 m_hitMapCl[i]->GetXaxis()->SetTitle(
"u position [pitch units]");
304 m_hitMapCl[i]->GetYaxis()->SetTitle(
"v position [pitch units]");
305 m_hitMapCl[i]->GetZaxis()->SetTitle(
"hits");
310 name = str(format(
"PXD_%1%_Seed") % sensorDescr);
311 title = str(format(
"PXD Sensor %1% Seed charge") % sensorDescr);
312 m_seed[i] =
new TH1F(name.c_str(), title.c_str(), 256, 0, 256);
313 m_seed[i]->GetXaxis()->SetTitle(
"seed charge of clusters [ADU]");
314 m_seed[i]->GetYaxis()->SetTitle(
"count");
321 void PXDDQMClustersModule::initialize()
327 m_storeDAQEvtStats.isOptional();
329 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
330 if (gTools->getNumberOfPXDLayers() != 0) {
334 RelationArray relPXDClusterDigits(storePXDClusters, storePXDDigits);
335 m_storePXDClustersName = storePXDClusters.getName();
336 m_relPXDClusterDigitName = relPXDClusterDigits.
getName();
339 m_storePXDDigitsName = storePXDDigits.getName();
343 void PXDDQMClustersModule::beginRun()
345 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
346 if (gTools->getNumberOfPXDLayers() == 0)
return;
348 if (m_hitMapCounts !=
nullptr) m_hitMapCounts->Reset();
349 if (m_hitMapClCounts !=
nullptr) m_hitMapClCounts->Reset();
350 if (m_hitMapCountsChip !=
nullptr) m_hitMapCountsChip->Reset();
351 if (m_hitMapClCountsChip !=
nullptr) m_hitMapClCountsChip->Reset();
353 for (
int i = 0; i < gTools->getNumberOfPXDSensors(); i++) {
354 if (m_fired[i] !=
nullptr) m_fired[i]->Reset();
355 if (m_clusters[i] !=
nullptr) m_clusters[i]->Reset();
356 if (m_startRow[i] !=
nullptr) m_startRow[i]->Reset();
357 if (m_chargStartRow[i] !=
nullptr) m_chargStartRow[i]->Reset();
358 if (m_startRowCount[i] !=
nullptr) m_startRowCount[i]->Reset();
359 if (m_clusterCharge[i] !=
nullptr) m_clusterCharge[i]->Reset();
360 if (m_clusterEnergy[i] !=
nullptr) m_clusterEnergy[i]->Reset();
361 if (m_pixelSignal[i] !=
nullptr) m_pixelSignal[i]->Reset();
362 if (m_clusterSizeU[i] !=
nullptr) m_clusterSizeU[i]->Reset();
363 if (m_clusterSizeV[i] !=
nullptr) m_clusterSizeV[i]->Reset();
364 if (m_clusterSizeUV[i] !=
nullptr) m_clusterSizeUV[i]->Reset();
366 if (m_hitMapU[i] !=
nullptr) m_hitMapU[i]->Reset();
367 if (m_hitMapV[i] !=
nullptr) m_hitMapV[i]->Reset();
368 if (m_hitMap[i] !=
nullptr) m_hitMap[i]->Reset();
369 if (m_hitMapUCl[i] !=
nullptr) m_hitMapUCl[i]->Reset();
370 if (m_hitMapVCl[i] !=
nullptr) m_hitMapVCl[i]->Reset();
371 if (m_hitMapCl[i] !=
nullptr) m_hitMapCl[i]->Reset();
372 if (m_seed[i] !=
nullptr) m_seed[i]->Reset();
378 void PXDDQMClustersModule::event()
380 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
381 if (gTools->getNumberOfPXDLayers() == 0)
return;
385 const RelationArray relPXDClusterDigits(storePXDClusters, storePXDDigits, m_relPXDClusterDigitName);
388 if (!storePXDDigits || !storePXDDigits.
getEntries())
return;
390 int firstPXDLayer = gTools->getFirstPXDLayer();
391 int lastPXDLayer = gTools->getLastPXDLayer();
392 int nPXDSensors = gTools->getNumberOfPXDSensors();
396 vector< int > Pixels(nPXDSensors);
397 for (
const PXDDigit& digit2 : storePXDDigits) {
398 int iLayer = digit2.getSensorID().getLayerNumber();
399 if ((iLayer < firstPXDLayer) || (iLayer > lastPXDLayer))
continue;
400 int iLadder = digit2.getSensorID().getLadderNumber();
401 int iSensor = digit2.getSensorID().getSensorNumber();
402 VxdID sensorID(iLayer, iLadder, iSensor);
403 int index = gTools->getPXDSensorIndex(sensorID);
406 int iChip = PXDMappingLookup::getDCDID(digit2.getUCellID(), digit2.getVCellID(), sensorID);
407 int indexChip = gTools->getPXDChipIndex(sensorID, kTRUE, iChip);
408 if (m_hitMapCountsChip !=
nullptr) m_hitMapCountsChip->Fill(indexChip);
409 iChip = PXDMappingLookup::getSWBID(digit2.getVCellID());
410 indexChip = gTools->getPXDChipIndex(sensorID, kFALSE, iChip);
411 if (m_hitMapCountsChip !=
nullptr) m_hitMapCountsChip->Fill(indexChip);
412 if (m_pixelSignal[index] !=
nullptr) m_pixelSignal[index]->Fill(digit2.getCharge());
413 if (digit2.getCharge() < m_CutPXDCharge)
continue;
414 if (m_hitMapCounts !=
nullptr) m_hitMapCounts->Fill(index);
415 if (m_hitMapU[index] !=
nullptr) m_hitMapU[index]->Fill(digit2.getUCellID());
416 if (m_hitMapV[index] !=
nullptr) m_hitMapV[index]->Fill(digit2.getVCellID());
417 if (m_hitMap[index] !=
nullptr) m_hitMap[index]->Fill(digit2.getUCellID(), digit2.getVCellID());
420 for (
int i = 0; i < nPXDSensors; i++) {
421 if ((m_fired[i] !=
nullptr) && (Pixels[i] > 0)) m_fired[i]->Fill(Pixels[i]);
425 vector< int > counts(nPXDSensors);
426 for (
const PXDCluster& cluster : storePXDClusters) {
427 int iLayer = cluster.getSensorID().getLayerNumber();
428 if ((iLayer < firstPXDLayer) || (iLayer > lastPXDLayer))
continue;
429 int iLadder = cluster.getSensorID().getLadderNumber();
430 int iSensor = cluster.getSensorID().getSensorNumber();
431 VxdID sensorID(iLayer, iLadder, iSensor);
432 int index = gTools->getPXDSensorIndex(sensorID);
436 int indexChip = gTools->getPXDChipIndex(sensorID, kTRUE, iChip);
437 if (m_hitMapClCountsChip !=
nullptr) m_hitMapClCountsChip->Fill(indexChip);
439 indexChip = gTools->getPXDChipIndex(sensorID, kFALSE, iChip);
440 if (m_hitMapClCountsChip !=
nullptr) m_hitMapClCountsChip->Fill(indexChip);
441 if (m_hitMapClCounts !=
nullptr) m_hitMapClCounts->Fill(index);
442 if (m_clusterCharge[index] !=
nullptr) m_clusterCharge[index]->Fill(cluster.getCharge());
448 auto ADUToEnergy = PXDGainCalibrator::getInstance().getADUToEnergy(sensorID, cluster_uID, cluster_vID);
449 if (m_clusterEnergy[index] !=
nullptr) m_clusterEnergy[index]->Fill(cluster.getCharge()* ADUToEnergy / Unit::keV);
450 if (m_clusterSizeU[index] !=
nullptr) m_clusterSizeU[index]->Fill(cluster.getUSize());
451 if (m_clusterSizeV[index] !=
nullptr) m_clusterSizeV[index]->Fill(cluster.getVSize());
452 if (m_clusterSizeUV[index] !=
nullptr) m_clusterSizeUV[index]->Fill(cluster.getSize());
453 if (m_seed[index] !=
nullptr) m_seed[index]->Fill(cluster.getSeedCharge());
454 if (cluster.getCharge() < m_CutPXDCharge)
continue;
455 if (m_hitMapUCl[index] !=
nullptr) m_hitMapUCl[index]->Fill(
457 if (m_hitMapVCl[index] !=
nullptr) m_hitMapVCl[index]->Fill(
459 if (m_hitMapCl[index] !=
nullptr) m_hitMapCl[index]->Fill(
464 for (
int i = 0; i < nPXDSensors; i++) {
465 if ((m_clusters[i] !=
nullptr) && (counts[i] > 0))
466 m_clusters[i]->Fill(counts[i]);
470 if (m_storeDAQEvtStats.isValid()) {
471 std::map<VxdID, unsigned short> startRows;
472 for (
int index = 0; index < nPXDSensors; index++) {
473 VxdID id = gTools->getSensorIDFromPXDIndex(index);
476 if (dhe !=
nullptr) {
478 if (m_startRow[index] !=
nullptr) m_startRow[index]->Fill(startRow);
479 startRows.insert(std::make_pair(
id, startRow));
481 B2WARNING(
"No PXDDAQDHEStatus for VXD Sensor " <<
id <<
" found.");
486 for (
auto& cluster : storePXDClusters) {
487 VxdID sensorID = cluster.getSensorID();
488 int index = gTools->getPXDSensorIndex(sensorID);
493 if (m_chargStartRow[index] !=
nullptr) m_chargStartRow[index]->Fill(fDistance, cluster.getSeedCharge());
494 if (m_startRowCount[index] !=
nullptr) m_startRowCount[index]->Fill(fDistance);