10#include <klm/modules/KLMStripEfficiencyCollector/KLMStripEfficiencyCollectorModule.h>
11#include <klm/dataobjects/KLMChannelIndex.h>
14#include <CLHEP/Vector/ThreeVector.h>
24 m_GeometryBKLM(nullptr),
26 m_MatchingFile(nullptr),
27 m_MatchingTree(nullptr),
28 m_MatchingHitData({0, 0, 0, 0, 0, 0, 0.,
nullptr,
nullptr}),
31 setDescription(
"Module for KLM strip efficiency data collection.");
33 std::string(
"mu+:all"));
35 "Maximal distance in the units of strip number from ExtHit to "
36 "matching KLMDigit (not for multi-strip hits).",
double(8));
38 "Minimal number of matching digits.", 0);
39 addParam(
"MinimalMatchingDigitsOuterLayers",
41 "Minimal number of matching digits in outer layers.", 0);
43 "Minimal momentum in case there are no hits in outer layers.", 0.0);
45 "Whether to remove unused muons.",
false);
47 "Whether to ignore ExtHits with backward propagation.",
false);
64 TH1F* matchedDigitsInPlane =
new TH1F(
65 "matchedDigitsInPlane",
"Number of matching KLMDigits",
66 nPlanes, -0.5,
double(nPlanes) - 0.5);
67 TH1F* allExtHitsInPlane =
new TH1F(
68 "allExtHitsInPlane",
"Number of ExtHits",
69 nPlanes, -0.5,
double(nPlanes) - 0.5);
70 registerObject<TH1F>(
"matchedDigitsInPlane", matchedDigitsInPlane);
71 registerObject<TH1F>(
"allExtHitsInPlane", allExtHitsInPlane);
100 B2FATAL(
"KLM channel status data are not available.");
101 int minimalActivePlanes = -1;
106 int activePlanes = 0;
109 for (; klmPlane != klmNextSector; ++klmPlane) {
112 bool isActive =
false;
115 for (; klmChannel != klmNextPlane; ++ klmChannel) {
120 B2FATAL(
"Incomplete KLM channel status data.");
134 if (activePlanes == 0)
136 if (minimalActivePlanes < 0)
137 minimalActivePlanes = activePlanes;
138 else if (minimalActivePlanes < activePlanes)
139 minimalActivePlanes = activePlanes;
141 if ((minimalActivePlanes >= 0) &&
143 B2WARNING(
"The minimal number of active planes (" << minimalActivePlanes <<
144 ") is less than the minimal number of matching digits (" <<
146 "matching digits is reduced to make the calibration possible.");
157 std::vector<unsigned int> toRemove;
158 unsigned int nMuons =
m_MuonList->getListSize();
165 TH1F* matchedDigitsInPlane = getObjectPtr<TH1F>(
"matchedDigitsInPlane");
166 TH1F* allExtHitsInPlane = getObjectPtr<TH1F>(
"allExtHitsInPlane");
167 for (
unsigned int i = 0; i < nMuons; ++i) {
179 std::map<KLMPlaneNumber, struct HitData>& hitMap,
182 std::map<KLMPlaneNumber, struct HitData>::iterator it;
183 it = hitMap.find(planeGlobal);
188 if (it == hitMap.end()) {
189 hitMap.insert(std::pair<KLMPlaneNumber, struct HitData>(
190 planeGlobal, *hitData));
198 if (!(digit.getSubdetector() == hitData->
subdetector &&
199 digit.getSection() == hitData->
section &&
200 digit.getLayer() == hitData->
layer &&
201 digit.getSector() == hitData->
sector &&
202 digit.getPlane() == hitData->
plane))
205 double stripPosition = digit.getStrip();
208 if (digit.isMultiStrip()) {
209 stripPosition = 0.5 * (digit.getLastStrip() + digit.getStrip());
210 allowedDistance1D *= (digit.getLastStrip() - digit.getStrip() + 1);
212 if (fabs(stripPosition - hitData->
strip) < allowedDistance1D) {
213 hitData->
digit = &digit;
220 const Particle* muon, TH1F* matchedDigitsInPlane, TH1F* allExtHitsInPlane)
222 const int nExtrapolationLayers =
226 std::map<KLMPlaneNumber, struct HitData> selectedHits;
227 std::map<KLMPlaneNumber, struct HitData>::iterator it;
230 struct HitData hitData, hitDataPrevious;
231 ROOT::Math::XYZVector extHitPosition;
232 CLHEP::Hep3Vector extHitPositionCLHEP, localPosition;
234 int extHitLayer[nExtrapolationLayers] = {0};
235 int digitLayer[nExtrapolationLayers] = {0};
239 hitDataPrevious.
sector = -1;
240 hitDataPrevious.
layer = -1;
241 for (
const ExtHit& hit : extHits) {
248 if (hit.getStatus() != EXT_EXIT)
257 if (hit.isBackwardPropagated())
262 hitData.
digit =
nullptr;
263 if (hit.getDetectorID() == Const::EDetector::EKLM) {
264 int stripGlobal = hit.getCopyID();
274 B2FATAL(
"Incomplete KLM channel status data.");
278 extHitLayer[layer - 1]++;
282 addHit(selectedHits, planeGlobal, &hitData);
284 }
else if (hit.getDetectorID() == Const::EDetector::BKLM) {
285 int moduleNumber = hit.getCopyID();
302 B2FATAL(
"Incomplete KLM channel status data.");
306 extHitLayer[layer - 1]++;
310 addHit(selectedHits, planeGlobal, &hitData);
314 extHitPosition = hit.getPosition();
315 extHitPositionCLHEP.setX(extHitPosition.X());
316 extHitPositionCLHEP.setY(extHitPosition.Y());
317 extHitPositionCLHEP.setZ(extHitPosition.Z());
321 localPosition = module->globalToLocal(extHitPositionCLHEP);
323 hitData.
strip = module->getZStrip(localPosition);
335 std::memcpy(&hitDataPrevious, &hitData,
sizeof(
struct HitData));
339 hitData.
strip,
false)) {
345 B2FATAL(
"Incomplete KLM channel status data.");
349 extHitLayer[layer - 1]++;
354 addHit(selectedHits, planeGlobal, &hitData);
358 hitData.
strip = module->getPhiStrip(localPosition);
362 hitData.
strip,
false)) {
368 B2FATAL(
"Incomplete KLM channel status data.");
372 extHitLayer[layer - 1]++;
377 addHit(selectedHits, planeGlobal, &hitData);
386 for (it = selectedHits.begin(); it != selectedHits.end(); ++it) {
388 if (it->second.digit !=
nullptr) {
391 it->second.subdetector, it->second.layer);
392 digitLayer[layer - 1]++;
398 for (it = selectedHits.begin(); it != selectedHits.end(); ++it) {
399 int matchingDigits = 0;
400 int matchingDigitsOuterLayers = 0;
401 int extHitsOuterLayers = 0;
403 it->second.subdetector, it->second.layer) - 1;
404 for (
int i = 0; i < nExtrapolationLayers; ++i) {
406 matchingDigits += digitLayer[i];
408 matchingDigitsOuterLayers += digitLayer[i];
409 extHitsOuterLayers += extHitLayer[i];
436 if (it->second.digit) {
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 void moduleNumberToElementNumbers(KLMModuleNumber module, int *section, int *sector, int *layer)
Get element numbers by module number.
Calibration collector module base class.
void stripNumberToElementNumbers(int stripGlobal, int *section, int *layer, int *sector, int *plane, int *strip) const
Get element numbers by strip global number.
Store one Ext hit as a ROOT object.
@ c_IndexLevelSector
Sector.
@ c_IndexLevelStrip
Strip.
@ c_IndexLevelPlane
Plane.
KLMChannelNumber getKLMChannelNumber() const
Get KLM channel number.
void setIndexLevel(enum IndexLevel indexLevel)
Set index level.
ChannelStatus
Channel status.
@ c_Normal
Normally operating channel.
@ c_Unknown
Unknown status (no data).
KLM digit (class representing a digitized hit in RPCs or scintillators).
uint16_t getNElements() const
Get number of elements.
uint16_t getIndex(uint16_t number) const
Get element index.
KLMChannelNumber channelNumberBKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for BKLM.
KLMPlaneNumber planeNumberEKLM(int section, int sector, int layer, int plane) const
Get channel number for EKLM.
int getExtrapolationLayer(int subdetector, int layer) const
Get extrapolation layer number (BKLM - from 1 to 15, EKLM - from 16 to 29).
KLMPlaneNumber planeNumberBKLM(int section, int sector, int layer, int plane) const
Get plane number for BKLM.
static constexpr int getMaximalExtrapolationLayer()
Get maximal extrapolation layer.
KLMChannelNumber channelNumberEKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for EKLM.
TTree * m_MatchingTree
Matching data tree.
~KLMStripEfficiencyCollectorModule()
Destructor.
const bklm::GeometryPar * m_GeometryBKLM
BKLM geometry.
void addHit(std::map< KLMPlaneNumber, struct HitData > &hitMap, KLMPlaneNumber planeGlobal, struct HitData *hitData)
Add hit to map.
int m_MatchedStrip
Matched strip.
StoreArray< KLMDigit > m_Digits
KLM digits.
DBObjPtr< KLMChannelStatus > m_ChannelStatus
Channel status.
void startRun() override
This method is called at the beginning of the run.
double m_MinimalMomentumNoOuterLayers
Minimal momentum in case there are no hits in outer layers.
TFile * m_MatchingFile
Matching data file.
bool m_RemoveUnusedMuons
Whether to remove unused muons.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
const KLMPlaneArrayIndex * m_PlaneArrayIndex
Plane array index.
const EKLMElementNumbers * m_eklmElementNumbers
EKLM element numbers.
void findMatchingDigit(struct HitData *hitData)
Find matching digit.
KLMStripEfficiencyCollectorModule()
Constructor.
void collect() override
This method is called for each event.
StoreObjPtr< ParticleList > m_MuonList
Muons.
StoreArray< Track > m_tracks
Tracks.
bool collectDataTrack(const Particle *muon, TH1F *matchedDigitsInPlane, TH1F *allExtHitsInPlane)
Collect the data for one muon.
void closeRun() override
This method is called at the end of run.
bool m_IgnoreBackwardPropagation
Whether to ignore ExtHits with backward propagation.
struct HitData m_MatchingHitData
Matching hit data.
double m_AllowedDistance1D
Maximal distance in the units of strip number from ExtHit to matching KLMDigit.
void prepare() override
Initializer.
std::string m_MatchingFileName
Matching data file name.
void finish() override
Finish data processing.
StoreArray< ExtHit > m_extHits
ExtHits.
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.
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.
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
Class that bundles various TrackFitResults.
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
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.
Abstract base class for different kinds of events.
int subdetector
Subdetector.
double localPosition
Local coordinate.
const KLMDigit * digit
Digit.
const ExtHit * hit
Extrapolation hit.