10#include <klm/modules/KLMDQM2/KLMDQM2Module.h>
13#include <mdst/dataobjects/Track.h>
16#include <TDirectory.h>
19#include <CLHEP/Vector/ThreeVector.h>
51 setDescription(R
"DOC(Additional Module for KLMDQM plots after HLT filters
53 An additional module developed to display plane efficiencies for the KLM during runs (i.e. for online analyses).
54 This module would be called after HLT filter in order to use mumu-tight skim to select reasonable events.
55 The output histograms would be plane efficiencies = MatchedDigits/AllExtits.
60 std::string(
"mu+:all"));
62 "Maximal distance in the units of strip number from ExtHit to "
63 "matching KLMDigit (not for multi-strip hits).",
double(8));
65 "Minimal number of matching digits.", 0);
66 addParam(
"MinimalMatchingDigitsOuterLayers",
68 "Minimal number of matching digits in outer layers.", 0);
70 "Minimal momentum in case there are no hits in outer layers.", 0.0);
72 "Whether to remove unused muons.",
false);
74 "Whether to ignore ExtHits with backward propagation.",
false);
77 "Directory for KLM DQM histograms in ROOT file.",
78 std::string(
"KLMEfficiencyDQM"));
80 "Software Trigger for event selection",
81 std::string(
"software_trigger_cut&skim&accept_mumutight"));
93 TDirectory::TContext context{gDirectory, newDirectory};
103 "Matched Hits in BKLM Plane",
108 "All ExtHits in BKLM Plane",
115 "Matched Hits in EKLM Plane",
120 "All ExtHits in EKLM Plane",
133 "Matched Hits in BKLM Sector",
134 BKLMMaxSectors, 0.5, 0.5 + BKLMMaxSectors);
138 "All ExtHits in BKLM Sector",
139 BKLMMaxSectors, 0.5, 0.5 + BKLMMaxSectors);
145 "Matched Hits in EKLM Sector",
146 EKLMMaxSectors, 0.5, EKLMMaxSectors + 0.5);
150 "All ExtHits in EKLM Sector",
151 EKLMMaxSectors, 0.5, EKLMMaxSectors + 0.5);
185 unsigned int nMuons =
m_MuonList->getListSize();
186 for (
unsigned int i = 0; i < nMuons; ++i) {
214 }
catch (
const std::out_of_range&) {
226 if (!(digit.getSubdetector() == hitData->
subdetector &&
227 digit.getSection() == hitData->
section &&
228 digit.getLayer() == hitData->
layer &&
229 digit.getSector() == hitData->
sector &&
230 digit.getPlane() == hitData->
plane) ||
235 double stripPosition = digit.getStrip();
238 if (digit.isMultiStrip()) {
240 stripPosition = 0.5 * (digit.getLastStrip() + digit.getStrip());
241 allowedDistance1D *= (digit.getLastStrip() - digit.getStrip() + 1);
243 if (fabs(stripPosition - hitData->
strip) < allowedDistance1D) {
244 hitData->
digit = &digit;
251 std::map<KLMPlaneNumber, struct HitData>& hitMap,
254 std::map<KLMPlaneNumber, struct HitData>::iterator it;
255 it = hitMap.find(planeGlobal);
260 if (it == hitMap.end()) {
261 hitMap.insert(std::pair<KLMPlaneNumber, struct HitData>(
262 planeGlobal, *hitData));
267 const Particle* muon, TH1F* matchedHitsBKLM, TH1F* allExtHitsBKLM,
268 TH1F* matchedHitsEKLM, TH1F* allExtHitsEKLM, TH1F* matchedHitsBKLMSec, TH1F* allExtHitsBKLMSec,
269 TH1F* matchedHitsEKLMSec, TH1F* allExtHitsEKLMSec)
271 const int nExtrapolationLayers =
275 std::map<KLMPlaneNumber, struct HitData> selectedHits;
276 std::map<KLMPlaneNumber, struct HitData>::iterator it;
279 struct HitData hitData, hitDataPrevious;
280 ROOT::Math::XYZVector extHitPosition;
281 CLHEP::Hep3Vector extHitPositionCLHEP, localPosition;
283 int extHitLayer[nExtrapolationLayers] = {0};
284 int digitLayer[nExtrapolationLayers] = {0};
288 hitDataPrevious.
sector = -1;
289 hitDataPrevious.
layer = -1;
290 for (
const ExtHit& hit : extHits) {
297 if (hit.getStatus() != EXT_EXIT)
306 if (hit.isBackwardPropagated())
311 hitData.
digit =
nullptr;
312 if (hit.getDetectorID() == Const::EDetector::EKLM) {
313 int stripGlobal = hit.getCopyID();
323 B2FATAL(
"Incomplete KLM channel status data.");
327 extHitLayer[layer - 1]++;
331 addHit(selectedHits, planeGlobal, &hitData);
333 }
else if (hit.getDetectorID() == Const::EDetector::BKLM) {
334 int moduleNumber = hit.getCopyID();
351 B2FATAL(
"Incomplete KLM channel status data.");
355 extHitLayer[layer - 1]++;
359 addHit(selectedHits, planeGlobal, &hitData);
363 extHitPosition = hit.getPosition();
364 extHitPositionCLHEP.setX(extHitPosition.X());
365 extHitPositionCLHEP.setY(extHitPosition.Y());
366 extHitPositionCLHEP.setZ(extHitPosition.Z());
370 localPosition =
module->globalToLocal(extHitPositionCLHEP);
372 hitData.
strip =
module->getZStrip(localPosition);
384 std::memcpy(&hitDataPrevious, &hitData,
sizeof(
struct HitData));
388 hitData.
strip,
false)) {
394 B2FATAL(
"Incomplete KLM channel status data.");
398 extHitLayer[layer - 1]++;
403 addHit(selectedHits, planeGlobal, &hitData);
407 hitData.
strip =
module->getPhiStrip(localPosition);
411 hitData.
strip,
false)) {
417 B2FATAL(
"Incomplete KLM channel status data.");
421 extHitLayer[layer - 1]++;
426 addHit(selectedHits, planeGlobal, &hitData);
435 for (it = selectedHits.begin(); it != selectedHits.end(); ++it) {
437 if (it->second.digit !=
nullptr) {
440 it->second.subdetector, it->second.layer);
441 digitLayer[layer - 1]++;
447 for (it = selectedHits.begin(); it != selectedHits.end(); ++it) {
448 int matchingDigits = 0;
449 int matchingDigitsOuterLayers = 0;
450 int extHitsOuterLayers = 0;
452 it->second.subdetector, it->second.layer) - 1;
453 for (
int i = 0; i < nExtrapolationLayers; ++i) {
455 matchingDigits += digitLayer[i];
457 matchingDigitsOuterLayers += digitLayer[i];
458 extHitsOuterLayers += extHitLayer[i];
486 int planeNum =
m_eklmElementNumbers->planeNumber(it->second.section, it->second.layer, it->second.sector, it->second.plane);
488 allExtHitsEKLM->Fill(planeNum);
489 allExtHitsEKLMSec->Fill(sectorNum);
490 if (it->second.digit) {
491 matchedHitsEKLM->Fill(planeNum);
492 matchedHitsEKLMSec->Fill(sectorNum);
499 it->second.section, it->second.sector, it->second.layer);
501 allExtHitsBKLM->Fill(layerGlobal);
502 allExtHitsBKLMSec->Fill(sectorGlobal);
503 if (it->second.digit) {
504 matchedHitsBKLM->Fill(layerGlobal);
505 matchedHitsBKLMSec->Fill(sectorGlobal);
508 B2FATAL(
"Had a hit that didn't come from BKLM or EKLM?");
static void channelNumberToElementNumbers(KLMChannelNumber channel, int *section, int *sector, int *layer, int *plane, int *strip)
Get element numbers by channel number.
static bool checkChannelNumber(int section, int sector, int layer, int plane, int strip, bool fatalError=true)
Check channel number.
@ c_FirstRPCLayer
First RPC layer.
static constexpr int getMaximalSectorNumber()
Get maximal sector number (1-based).
static void moduleNumberToElementNumbers(KLMModuleNumber module, int *section, int *sector, int *layer)
Get element numbers by module number.
static constexpr int getMaximalSectorGlobalNumber()
Get maximal sector global number.
static int layerGlobalNumber(int section, int sector, int layer)
Get layer global number.
static constexpr int getMaximalSectorNumber()
Get maximal sector number.
static constexpr int getMaximalSectorGlobalNumberKLMOrder()
Get maximal sector global number with KLM ordering (section, sector).
Store one Ext hit as a ROOT object.
HistoModule()
Constructor.
ChannelStatus
Channel status.
@ c_Normal
Normally operating channel.
@ c_Unknown
Unknown status (no data).
TH1F * m_MatchedHitsBKLMSector
Matched hits in sector for BKLM.
TH1F * m_MatchedHitsEKLM
Matched hits in plane for EKLM.
const bklm::GeometryPar * m_GeometryBKLM
BKLM geometry.
void addHit(std::map< KLMPlaneNumber, struct HitData > &hitMap, KLMPlaneNumber planeGlobal, struct HitData *hitData)
Add hit to map.
StoreArray< KLMDigit > m_Digits
KLM digits.
DBObjPtr< KLMChannelStatus > m_ChannelStatus
Channel status.
TH1F * m_AllExtHitsBKLMSector
Extrapolated hits in sector for BKLM.
virtual void initialize() override
Register input and output data.
double m_MinimalMomentumNoOuterLayers
Minimal momentum in case there are no hits in outer layers.
bool m_RemoveUnusedMuons
Whether to remove unused muons.
virtual void event() override
Selection for mumu_tight_skim, then DQM plot filling.
const KLMElementNumbers * m_ElementNumbers
KLM element numbers.
const KLMPlaneArrayIndex * m_PlaneArrayIndex
Plane array index.
virtual void endRun() override
Called if the current run ends.
const EKLMElementNumbers * m_eklmElementNumbers
EKLM element numbers.
virtual void terminate() override
Called at the end of the event processing.
void findMatchingDigit(struct HitData *hitData)
Find matching digit.
std::string m_SoftwareTriggerName
Software Trigger Name.
TH1F * m_AllExtHitsEKLMSector
Extrapolated hits in sector for EKLM.
TH1F * m_MatchedHitsBKLM
Matched hits in plane for BKLM.
StoreObjPtr< ParticleList > m_MuonList
Muons.
virtual void beginRun() override
Called when entering a new run.
bool m_IgnoreBackwardPropagation
Whether to ignore ExtHits with backward propagation.
double m_AllowedDistance1D
Maximal distance in the units of strip number from ExtHit to matching KLMDigit.
KLMDQM2Module()
Constructor: Sets the description, the properties and the parameters of the module.
~KLMDQM2Module()
Destructor.
TH1F * m_AllExtHitsBKLM
Extrapolated hits in plane for BKLM.
TH1F * m_MatchedHitsEKLMSector
Matched hits in sector for EKLM.
const int m_PlaneNumBKLM
Number of layers/planes for BKLM.
int m_MinimalMatchingDigitsOuterLayers
Minimal number of matching digits in outer layers.
std::string m_MuonListName
Muon list name.
int m_MinimalMatchingDigits
Minimal number of matching digits.
StoreObjPtr< SoftwareTriggerResult > m_softwareTriggerResult
Trigger Information.
const int m_PlaneNumEKLM
Number of layers/planes for EKLM.
TH1F * m_AllExtHitsEKLM
Extrapolated hits in plane for EKLM.
bool collectDataTrack(const Particle *muon, TH1F *matchedHitsBKLM, TH1F *allExtHitsBKLM, TH1F *matchedHitsEKLM, TH1F *allExtHitsEKLM, TH1F *matchedHitsBKLMSec, TH1F *allExtHitsBKLMSec, TH1F *matchedHitsEKLMSec, TH1F *allExtHitsEKLMSec)
Collect the data for one muon.
bool triggerFlag()
Uses TrigResult along with desired software cut to determine whether histograms are filled or not for...
std::string m_HistogramDirectoryName
Directory for KLM DQM histograms in ROOT file.
void defineHisto() override
Definition of the histograms.
KLM digit (class representing a digitized hit in RPCs or scintillators).
static constexpr int getMaximalExtrapolationLayer()
Get maximal extrapolation layer.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class to store reconstructed particles.
const Track * getTrack() const
Returns the pointer to the Track object that was used to create this Particle (ParticleType == c_Trac...
double getP() const
Returns momentum magnitude (same as getMomentumMagnitude but with shorter name)
Class for type safe access to objects that are referred to in relations.
Class that bundles various TrackFitResults.
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
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 KLMChannelNumber
Channel number.
uint16_t KLMPlaneNumber
Plane number.
@ c_accept
Accept this event.
Abstract base class for different kinds of events.
int subdetector
Subdetector.
double localPosition
Local coordinate.
const KLMDigit * digit
Digit.
const ExtHit * hit
Extrapolation hit.