10#include <dqm/analysis/modules/DQMHistAnalysisKLM.h>
13#include <klm/dataobjects/KLMChannelIndex.h>
38 "Threshold X for masked channels: if a channel has an occupancy X times larger than the average, it will be masked.", 100);
40 "Threshold Y for hot channels: if a channel has an occupancy Y times larger than the average, it will be marked as hot (but not masked).",
43 "Threshold Z for log scale view: if a channel has an occupancy Z times larger than the average, canvas shifts to log scale.",
48 "Minimal number of processed events required to print error messages", 10000.);
50 "Minimal number for delta histogram updates", 50000.);
52 "Max number of messages to show up in channel occupancy plots", 12);
74 B2FATAL(
"The threshold used for hot channels is larger than the one for masked channels."
105 bklmSectors * 2, 0.5, 0.5 + bklmSectors * 2);
113 eklmPlanes, 0.5, 0.5 + eklmPlanes);
126 for (
int j = 0; j < nHistograms; j++) {
127 str =
"strip_hits_subdetector_" +
128 std::to_string(klmSector.getSubdetector()) +
129 "_section_" + std::to_string(klmSector.getSection()) +
130 "_sector_" + std::to_string(klmSector.getSector()) +
131 "_" + std::to_string(j);
146 B2FATAL(
"No KLM electronics map.");
158 int hist_max_bin;
double max_position;
161 hist_max_bin = time_rpc->GetMaximumBin();
162 max_position = time_rpc->GetXaxis()->GetBinCenter(hist_max_bin);
163 m_monObj->setVariable(
"RPC_Time_Peak", max_position);
167 if (time_scint_bklm) {
168 hist_max_bin = time_scint_bklm->GetMaximumBin();
169 max_position = time_scint_bklm->GetXaxis()->GetBinCenter(hist_max_bin);
170 m_monObj->setVariable(
"BKLM_Scint_Time_Peak", max_position);
174 if (time_scint_eklm) {
175 hist_max_bin = time_scint_eklm->GetMaximumBin();
176 max_position = time_scint_eklm->GetXaxis()->GetBinCenter(hist_max_bin);
177 m_monObj->setVariable(
"EKLM_Scint_Time_Peak", max_position);
184 B2WARNING(
"Either DAQ/Nevent is not found or Nevent = 0.");
193 if (delta !=
nullptr) {
194 Double_t scale = (Double_t) histogram->Integral();
197 delta->SetLineColor(kBlackBody);
198 delta->SetLineStyle(4);
199 delta->DrawNormalized(
"SAME", scale);
206 int subdetector,
int section,
int sector,
int index,
207 TH1* histogram, TH1* delta, TCanvas* canvas, TLatex& latex)
213 std::map<KLMModuleNumber, double>::iterator it;
215 int channelSubdetector, channelSection, channelSector;
216 int layer, plane, strip;
220 histogram->SetStats(
false);
224 n = histogram->GetXaxis()->GetNbins();
228 if (ref_histogram) {ref_histogram->Draw(
"hist,same");}
229 float ref_average = 0;
231 if (ref_histogram !=
nullptr) {
232 for (i = 1; i <= n; i++) {
233 double nHitsPerModuleRef = ref_histogram->GetBinContent(i);
234 ref_average = ref_average + nHitsPerModuleRef;
238 for (i = 1; i <= n; i++) {
242 double nHitsPerModule = histogram->GetBinContent(i);
243 average = average + nHitsPerModule;
245 channelNumber, &channelSubdetector, &channelSection, &channelSector,
246 &layer, &plane, &strip);
247 if ((channelSubdetector != subdetector) ||
248 (channelSection != section) ||
249 (channelSector != sector))
250 B2FATAL(
"Inconsistent element numbers.");
252 subdetector, section, sector, layer);
256 module, nHitsPerModule));
258 it->second += nHitsPerModule;
261 unsigned int activeModuleChannels = 0;
262 int message_counter = 0;
265 if (it->second != 0) {
270 moduleNumber, &channelSubdetector, &channelSection, &channelSector, &layer);
274 channelSubdetector, channelSection, channelSector, layer, 1, 1);
277 if (electronicsChannel ==
nullptr)
278 B2FATAL(
"Incomplete KLM electronics map.");
279 str =
"No data from lane " + std::to_string(electronicsChannel->
getLane());
280 latex.DrawLatexNDC(x, y, str.c_str());
286 std::vector<KLMModuleNumber>::iterator ite =
300 if (activeModuleChannels == 0)
302 average /= activeModuleChannels;
303 ref_average /= activeModuleChannels;
305 for (i = 1; i <= n; ++i) {
309 double nHits = histogram->GetBinContent(i);
311 channelNumber, &channelSubdetector, &channelSection, &channelSector,
312 &layer, &plane, &strip);
313 std::string channelStatus =
"Normal";
315 channelStatus =
"Masked";
316 std::vector<KLMModuleNumber>::iterator ite =
322 B2DEBUG(20,
"KLM@MaskMe " << channelNumber);
324 channelStatus =
"Hot";
326 if (channelStatus !=
"Normal") {
329 if (electronicsChannel ==
nullptr)
330 B2FATAL(
"Incomplete BKLM electronics map.");
331 if (channelStatus ==
"Masked") {
332 histogram->SetBinContent(i, 0);
333 if (delta !=
nullptr)
334 delta->SetBinContent(i, 0);
336 str = channelStatus +
" channel: ";
338 str += (
"L" + std::to_string(electronicsChannel->
getLane()) +
339 " A" + std::to_string(electronicsChannel->
getAxis()) +
340 " Ch" + std::to_string(electronicsChannel->
getChannel()));
343 latex.DrawLatexNDC(x, y, str.c_str());
349 std::string verbose_message =
" more messages";
350 verbose_message = std::to_string(message_counter -
m_MessageThreshold) + verbose_message;
351 latex.DrawLatexNDC(x, y, verbose_message.c_str());
357 histogram->SetMinimum(1);
359 }
else if (ref_histogram !=
nullptr) {
362 histogram->SetMinimum(1);
377 if (subdetector == 1) {
386 for (
int k = 0; k < divisions; k++) {
387 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
393 if ((section == 2) && (index == 0 || index == 1))
397 for (
int k = 0; k < divisions; k++) {
398 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
413 histogram->SetStats(
false);
414 histogram->Draw(
"COLZ");
427 const std::string& histName)
430 if (histogram ==
nullptr) {
436 if (canvas ==
nullptr) {
448 if (delta !=
nullptr) {
449 B2INFO(
"DQMHistAnalysisKLM: Time Delta Entries is " << delta->GetEntries());
454 if (ref) {ref->Draw(
"hist,same");}
459 const std::string& histName)
462 if (histogram ==
nullptr) {
467 if (canvas ==
nullptr) {
476 int channelSubdetector, channelSection, channelSector;
477 int layer, plane, strip;
480 channel, &channelSubdetector, &channelSection, &channelSector,
481 &layer, &plane, &strip);
484 sectorNumber =
m_ElementNumbers->sectorNumberBKLM(channelSection, channelSector);
486 sectorNumber =
m_ElementNumbers->sectorNumberEKLM(channelSection, channelSector);
488 histogram->Fill(sectorIndex);
491 histogram->SetStats(
false);
498 const std::string& histName, TLatex* latex =
nullptr, TH1* histogram =
nullptr)
517 histogram->SetStats(
false);
523 ref->Draw(
"hist,same");
527 double xAlarm = 0.15, yAlarm = 0.8;
528 int message_counter = 0;
532 bool isBKLM = histName.find(
"bklm") != std::string::npos;
535 bool isFE = histName.find(
"fe") != std::string::npos;
543 int bin = maximalLayer * sector + 1;
544 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
545 double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
546 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
549 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
564 for (
int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
565 int bin = maxPlane * layerGlobal + 1;
566 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
567 double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
568 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
570 if (layerGlobal < maximalLayer) {
571 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
588 std::string verbose_string = std::to_string(message_counter -
m_MessageThreshold) +
" more messages";
589 latex->DrawLatexNDC(xAlarm, yAlarm, verbose_string.c_str());
598 TCanvas* canvas,
const std::vector<KLMModuleNumber>& deadModules,
599 TLatex* latex,
int& message_counter,
double xAlarm,
double yAlarm)
601 if (deadModules.empty()) {
605 int moduleSubdetector, moduleSection, moduleSector, moduleLayer;
606 m_ElementNumbers->moduleNumberToElementNumbers(module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
608 std::string alarm =
"No data from " +
m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector)
609 +
", layer " + std::to_string(moduleLayer);
612 latex->DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
626 const std::string& histName, TLatex& latex)
635 B2WARNING(
"processFEHistogram: feHist is null, exiting function.");
639 B2WARNING(
"processFEHistogram: canvas is null, cannot draw histograms.");
644 std::unique_ptr<TH1> feClone(
static_cast<TH1*
>(feHist->Clone()));
648 if (denominator !=
nullptr && numerator !=
nullptr) {
650 auto tempNumerator = std::unique_ptr<TH1>(
static_cast<TH1*
>(numerator->Clone()));
651 auto tempSum = std::unique_ptr<TH1>(
static_cast<TH1*
>(denominator->Clone()));
654 tempSum->Add(numerator);
657 feHist->Divide(tempNumerator.get(), tempSum.get(), 1.0, 1.0,
"B");
663 ref->Draw(
"hist,same");
664 B2INFO(
"processFEHistogram: Found and drew reference histogram.");
666 B2WARNING(
"processFEHistogram: Reference histogram not found.");
671 B2INFO(
"processFEHistogram: Updated canvas after first draw.");
674 auto deltaDenom =
getDelta(
"", denominator->GetName());
675 auto deltaNumer =
getDelta(
"", numerator->GetName());
678 if ((deltaNumer !=
nullptr) && (deltaDenom !=
nullptr)) {
679 B2INFO(
"DQMHistAnalysisKLM: FE Ratio Delta Num/Denom Entries is "
680 << deltaNumer->GetEntries() <<
"/" << deltaDenom->GetEntries());
683 auto deltaTempNumerator = std::unique_ptr<TH1>(
static_cast<TH1*
>(deltaNumer->Clone()));
684 auto deltaTempSum = std::unique_ptr<TH1>(
static_cast<TH1*
>(deltaDenom->Clone()));
687 deltaTempSum->Add(deltaNumer);
690 feClone->Divide(deltaTempNumerator.get(), deltaTempSum.get(), 1.0, 1.0,
"B");
691 feClone->SetLineColor(kOrange);
692 feClone->DrawCopy(
"SAME");
697 B2WARNING(
"processFEHistogram: Delta numerator or denominator not found.");
700 B2WARNING(
"processFEHistogram: Skipped histogram processing due to missing numerator/denominator.");
708 if (not(daqInclusion ==
nullptr)) {
709 int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin(
"Yes"));
710 if (isKlmIncluded == 0)
718 std::string str, histogramName, canvasName;
720 latex.SetTextColor(kRed);
721 latex.SetTextAlign(11);
730 for (
int j = 0; j < nHistograms; j++) {
731 str =
"strip_hits_subdetector_" +
732 std::to_string(klmSector.getSubdetector()) +
733 "_section_" + std::to_string(klmSector.getSection()) +
734 "_sector_" + std::to_string(klmSector.getSector()) +
735 "_" + std::to_string(j);
738 TH1* histogram =
findHist(histogramName);
740 auto delta =
getDelta(
"", histogramName);
742 if (histogram ==
nullptr) {
743 B2WARNING(
"KLM DQM histogram " << histogramName <<
" is not found.");
747 if (canvas ==
nullptr) {
748 B2WARNING(
"KLM DQM histogram canvas " << canvasName <<
" is not found.");
756 klmSector.getSubdetector(), klmSector.getSection(),
757 klmSector.getSector(), j, histogram, delta, canvas, latex);
762 gStyle->SetPalette(kLightTemperature);
769 for (
int j = 1; j <= maximalLayerNumber; ++j) {
770 str =
"spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
771 "_section_" + std::to_string(section) +
772 "_layer_" + std::to_string(j);
775 TH2F* histogram =
static_cast<TH2F*
>(
findHist(histogramName));
776 if (histogram ==
nullptr) {
777 B2ERROR(
"KLM DQM histogram " << histogramName <<
" is not found.");
781 if (canvas ==
nullptr) {
782 B2ERROR(
"KLM DQM histogram canvas " << canvasName <<
" is not found.");
796 if ((feStatus_bklm_scintillator_0 ==
nullptr || feStatus_bklm_scintillator_1 ==
nullptr)) {
797 B2INFO(
"Histograms needed for BKLM feature extraction computation are not found");
800 if ((feStatus_eklm_plane_0 ==
nullptr || feStatus_eklm_plane_1 ==
nullptr)) {
801 B2INFO(
"Histograms needed for EKLM feature extraction computation are not found");
804 gStyle->SetPalette(kBird);
806 latex.SetTextColor(kBlue);
821 B2DEBUG(20,
"Updating EPICS PVs for DQMHistAnalysisKLM");
825 B2INFO(
"DQMHistAnalysisKLM: Null run detected. No PV Update.");
828 auto* daqDataSize =
findHist(
"DAQ/KLMDataSize");
829 double meanDAQDataSize = 0.;
830 if (daqDataSize !=
nullptr) {
831 meanDAQDataSize = daqDataSize->GetMean();
833 B2WARNING(
"DQMHistAnalysisKLM: Cannot find KLMDataSize");
834 if ((daqDataSize !=
nullptr) and (meanDAQDataSize != 0.)) {
839 B2DEBUG(20,
"DQMHistAnalysisKLM: MaskedChannels " <<
m_MaskedChannels.size());
844 B2INFO(
"DQMHistAnalysisKLM: KLM Not included. No PV Update. ");
static constexpr int getMaximalLayerNumber()
Get maximal layer number (1-based).
static constexpr int getMaximalSectorNumber()
Get maximal sector number (1-based).
static constexpr int getMaximalSectorGlobalNumber()
Get maximal sector global number.
static int getNStrips(int section, int sector, int layer, int plane)
Get number of strips.
TLine m_PlaneLine
TLine for boundary in plane histograms.
double m_ProcessedEvents
Number of processed events.
void initialize() override final
Initializer.
int m_MessageThreshold
Message Threshold for expert pots.
void updateCanvasStatus(TCanvas *canvas, const std::vector< KLMModuleNumber > &deadModules, TLatex *latex, int &message_counter, double xAlarm, double yAlarm)
Helper function to update the canvas status based on dead modules.
void processPlaneHistogram(const std::string &histName, TLatex *latex, TH1 *histogram)
Process histogram containing the number of hits in plane.
TH1 * m_fe_eklm_ratio
Histogram for EKLM plane events fraction w/ FE.
int m_ThresholdForLog
Threshold for log scale.
double m_minEntries
Minimal number of entries for delta histogram update.
TCanvas * m_c_fe_eklm_ratio
Canvas for EKLM plane events fraction w/ FE.
int m_MinHitsForFlagging
Minimal number of hits for flagging.
const KLMElementNumbers * m_ElementNumbers
KLM element numbers.
const EKLMElementNumbers * m_EklmElementNumbers
EKLM element numbers.
void processSpatial2DHitEndcapHistogram(uint16_t section, TH2F *histogram, TCanvas *canvas)
Process spatial 2D hits histograms for endcap.
MonitoringObject * m_monObj
Monitoring object.
void processFEHistogram(TH1 *feHist, TH1 *denominator, TH1 *numerator, TCanvas *canvas)
Process histogram containing the efficiencies.
void deltaDrawer(TH1 *delta, TH1 *histogram, TCanvas *canvas)
Scales and draws desired delta histogram for current canvas.
void processTimeHistogram(const std::string &histName)
Process histogram containing the hit times.
std::vector< uint16_t > m_MaskedChannels
Vector of masked channels.
void terminate() override final
This method is called at the end of the event processing.
void event() override final
This method is called for each event.
TCanvas * m_c_fe_bklm_ratio
Canvas for BKLM plane events fraction w/ FE.
int m_ThresholdForHot
Threshold for hot channels.
TH1 * m_fe_bklm_ratio
Histogram for BKLM plane events fraction w/ FE.
std::vector< uint16_t > m_DeadBarrelModules
Vector of dead barrel modules.
std::string m_histogramDirectoryName
Name of histogram directory.
double m_MinProcessedEventsForMessagesInput
Input parameter for minimal number of processed events for error messages.
TText m_PlaneText
TText for names in plane histograms.
DBObjPtr< KLMElectronicsMap > m_ElectronicsMap
Electronics map.
DQMHistAnalysisKLMModule()
Constructor.
void endRun() override final
This method is called if the current run ends.
int m_ThresholdForMasked
Threshold for masked channels.
const KLMSectorArrayIndex * m_SectorArrayIndex
KLM sector array index.
void beginRun() override final
Called when entering a new run.
double m_MinProcessedEventsForMessages
Minimal number of processed events for error messages.
std::vector< uint16_t > m_DeadEndcapModules
Vector of dead endcap modules.
double getProcessedEvents()
Get number of processed events.
TLine m_2DHitsLine
TLine for background region in 2d hits histograms.
const KLMChannelArrayIndex * m_ChannelArrayIndex
KLM channel array index.
bool m_IsNullRun
Run type flag for null runs.
void analyseChannelHitHistogram(int subdetector, int section, int sector, int index, TH1 *histogram, TH1 *delta, TCanvas *canvas, TLatex &latex)
Analyse channel hit histogram.
void fillMaskedChannelsHistogram(const std::string &histName)
Fill histogram containing masked channels per sector.
TCanvas * findCanvas(TString cname)
Find canvas by name.
static TH1 * findRefHist(const std::string &histname, ERefScaling scaling=ERefScaling::c_RefScaleNone, const TH1 *hist=nullptr)
Get referencehistogram from list (no other search).
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
void colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
static const std::string & getRunType(void)
Get the list of the reference histograms.
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
DQMHistAnalysisModule()
Constructor / Destructor.
@ c_StatusTooFew
Not enough entries/event to judge.
@ c_StatusError
Analysis result: Severe issue found.
@ c_StatusGood
Analysis result: Good.
@ c_RefScaleEntries
to number of entries (integral)
@ c_RefScaleNone
no scaling
static int getEventProcessed(void)
Get the number of processed events.
int registerEpicsPV(std::string pvname, std::string keyname="")
EPICS related Functions.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
static constexpr int getNStripsSector()
Get number of strips in a sector.
static constexpr int getMaximalLayerGlobalNumber()
Get maximal detector layer global number.
static constexpr int getMaximalPlaneGlobalNumber()
Get maximal plane global number.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
static constexpr int getMaximalSectorNumber()
Get maximal sector number.
static constexpr int getMaximalPlaneNumber()
Get maximal plane number.
@ c_IndexLevelSection
Section.
@ c_IndexLevelSector
Sector.
void setIndexLevel(enum IndexLevel indexLevel)
Set index level.
BKLM electronics channel.
int getChannel() const
Get channel.
int getAxis() const
Get axis.
int getLane() const
Get lane.
void setDescription(const std::string &description)
Sets the description of the module.
Class to store variables with their name which were sent to the logging service.
TH2 * moduleHitMap(TH1 *hitMap, int moduleID)
Make hit map in HAPD view (12*12 channels).
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
uint16_t KLMSectorNumber
Sector number.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMSubdetectorNumber
Subdetector number.
uint16_t KLMModuleNumber
Module number.
uint16_t KLMSectionNumber
Section number.
Abstract base class for different kinds of events.