13. KLM (\(K_{L}^0\) and Muon Detector)

In the following we describe the klm package (documentation still under development).

13.1. Modules

This is a list of the klm modules. Some modules (in the klm/bklm and klm/eklm subfolders) that are currently used only for debugging or specific studies are omitted here.

KLMChannelStatusCollector

Module for KLM channel status calibration (data collection).

Package

klm

Library

libKLMChannelStatusCollector.so

Parameters
  • granularity (str, default=’run’)

    Granularity of data collection. Data is separated by runs (=run) or not separated at all (=all)

  • maxEventsPerRun (int, default=-1)

    Maximum number of events that will be collected per run. Effectively the code in the collect() function is only run for this number of events on each run. Then the collect() function is switched off until a new run that hasn’t collected the maximum yet begins. -1 is the default and means that the collector runs over all events.

    Note that this is useful for debugging and hard limiting the number of events passed to the collected. However you should be limiting the collected data yourself! Check if your collected data object has enough entries for an algorithm to complete and then stop filling. Controlling this limit via a module param is encouraged.

  • preScale (float, default=1.0)

    This controls the rate at which events are actually passed to the collect() function. An event passing through this module will only have the collect() function run on it it passes a random selection scaled by this parameter i.e. For preScale=1.0 all events are collected, but for preScale=0.5 only 50 percent will be. Since this is based on a random choice, you should set the random seed to a fixed value if you want repeatable results.

    Should be a float in range [0.0,1.0], default=1.0

KLMClusterEfficiency

Module for KLM cluster reconstruction efficiency studies.

Package

klm

Library

libKLMClusterEfficiency.so

Parameters
  • EventsClusterHistograms (int, default=0)

    Draw cluster histograms for this number of events.

  • OutputFile (str, default=’KLMClusterEfficiency.root’)

    Output file.

  • SaveClusterData (bool, default=False)

    Whether to save cluster data or not.

  • SaveReconstructionData (bool, default=True)

    Whether to save reconstruction data or not.

KLMClustersReconstructor

Unified BKLM/EKLM module for the reconstruction of KLMClusters.

Package

klm

Library

libKLMClustersReconstructor.so

Parameters
  • ClusterMode (str, default=’AnyHit’)

    Clusterization mode (‘AnyHit’ or ‘FirstHit’).

  • ClusteringAngle (float, default=0.26)

    Clustering angle (rad).

  • PositionMode (str, default=’FirstLayer’)

    Vertex position calculation mode (‘FullAverage’ or ‘FirstLayer’).

KLMDQM

KLM data quality monitor.

Package

klm

Library

libKLMDQM.so

Parameters
  • histogramDirectoryName (str, default=’KLM’)

    Directory for KLM DQM histograms in ROOT file.

KLMDigitTimeShifter

Shift the time of KLMDigits according to the cable delay corrections.

Package

klm

Library

libKLMDigitTimeShifter.so

KLMDigitizer

KLM digitization module: create KLMDigits from BKLMSimHits and EKLMSimHits.

Package

klm

Library

libKLMDigitizer.so

Parameters
  • Debug (bool, default=False)

    Debug mode (generates additional output files with histograms).

  • DigitizationInitialTime (int, default=-5)

    Initial digitization time in CTIME periods.

  • Efficiency (str, default=’Plane’)

    Efficiency determination mode (“Strip” or “Plane”).

  • SaveFPGAFit (bool, default=False)

    Save FPGA fit data and set a relation with KLMDigits.

  • SimulationMode (str, default=’Generic’)

    Simulation mode (“Generic” or “ChannelSpecific”).

KLMPacker

KLM raw data packer (creates RawKLM from KLMDigits).

Package

klm

Library

libKLMPacker.so

KLMReconstructor

Create BKLMHit1ds from KLMDigits and then create BKLMHit2ds from BKLMHit1ds; create EKLMHit2ds from KLMDigits.

Package

klm

Library

libKLMReconstructor.so

Parameters
  • CheckSegmentIntersection (bool, default=True)

    Check if segments intersect.

  • EventT0Correction (bool, default=True)

    Perform EventT0 correction (true) or not (false)

  • IfAlign (bool, default=True)

    Perform alignment correction (true) or not (false).

  • IgnoreHotChannels (bool, default=True)

    Use only Normal and Dead (for debugging) channels during 2d hit reconstruction

  • IgnoreScintillators (bool, default=False)

    Ignore scintillators (to debug their electronics mapping).

  • TimeCableDelayCorrection (bool, default=True)

    Perform cable delay time correction (true) or not (false).

KLMStripEfficiencyCollector

Module for KLM strip efficiency data collection.

Package

klm

Library

libKLMStripEfficiencyCollector.so

Parameters
  • AllowedDistance1D (float, default=8.0)

    Maximal distance in the units of strip number from ExtHit to matching KLMDigit.

  • Debug (bool, default=False)

    Debug mode.

  • DebugFileName (str, default=’matching.root’)

    Debug file name.

  • IgnoreBackwardPropagation (bool, default=False)

    Whether to ignore ExtHits with backward propagation.

  • MinimalMatchingDigits (int, default=0)

    Minimal number of matching digits.

  • MinimalMatchingDigitsOuterLayers (int, default=0)

    Minimal number of matching digits in outer layers.

  • MinimalMomentumNoOuterLayers (float, default=0.0)

    Minimal momentum in case there are no hits in outer layers.

  • MuonListName (str, default=’mu+:all’)

    Muon list name.

  • RemoveUnusedMuons (bool, default=False)

    Whether to remove unused muons.

  • granularity (str, default=’run’)

    Granularity of data collection. Data is separated by runs (=run) or not separated at all (=all)

  • maxEventsPerRun (int, default=-1)

    Maximum number of events that will be collected per run. Effectively the code in the collect() function is only run for this number of events on each run. Then the collect() function is switched off until a new run that hasn’t collected the maximum yet begins. -1 is the default and means that the collector runs over all events.

    Note that this is useful for debugging and hard limiting the number of events passed to the collected. However you should be limiting the collected data yourself! Check if your collected data object has enough entries for an algorithm to complete and then stop filling. Controlling this limit via a module param is encouraged.

  • preScale (float, default=1.0)

    This controls the rate at which events are actually passed to the collect() function. An event passing through this module will only have the collect() function run on it it passes a random selection scaled by this parameter i.e. For preScale=1.0 all events are collected, but for preScale=0.5 only 50 percent will be. Since this is based on a random choice, you should set the random seed to a fixed value if you want repeatable results.

    Should be a float in range [0.0,1.0], default=1.0

KLMTimeCollector

Module for KLM time calibration (data collection).

Package

klm

Library

libKLMTimeCollector.so

Parameters
  • IgnoreBackwardPropagation (bool, default=False)

    Whether to ignore ExtHits with backward propagation.

  • debug (bool, default=False)

    debug mode.

  • granularity (str, default=’run’)

    Granularity of data collection. Data is separated by runs (=run) or not separated at all (=all)

  • inputParticleList (str, default=’mu+:cali’)

    input particle list.

  • maxEventsPerRun (int, default=-1)

    Maximum number of events that will be collected per run. Effectively the code in the collect() function is only run for this number of events on each run. Then the collect() function is switched off until a new run that hasn’t collected the maximum yet begins. -1 is the default and means that the collector runs over all events.

    Note that this is useful for debugging and hard limiting the number of events passed to the collected. However you should be limiting the collected data yourself! Check if your collected data object has enough entries for an algorithm to complete and then stop filling. Controlling this limit via a module param is encouraged.

  • preScale (float, default=1.0)

    This controls the rate at which events are actually passed to the collect() function. An event passing through this module will only have the collect() function run on it it passes a random selection scaled by this parameter i.e. For preScale=1.0 all events are collected, but for preScale=0.5 only 50 percent will be. Since this is based on a random choice, you should set the random seed to a fixed value if you want repeatable results.

    Should be a float in range [0.0,1.0], default=1.0

  • useEventT0 (bool, default=True)

    Use event T0 or not.

KLMUnpacker

KLM unpacker (creates KLMDigits from RawKLM).

Package

klm

Library

libKLMUnpacker.so

Parameters
  • DAQChannelBKLMScintillators (bool, default=False)

    Record DAQ channel for BKLM scintillators.

  • DAQChannelModule (int, default=-1)

    Record DAQ channel for specific module.

  • DebugElectronicsMap (bool, default=False)

    Debug electronics map (record DAQ channel instead of strip).

  • IgnoreStrip0 (bool, default=True)

    Ignore hits with strip = 0 (normally expected for certain firmware versions).

  • IgnoreWrongHits (bool, default=False)

    Ignore wrong hits (i.e. no B2ERROR).

  • WriteDigitRaws (bool, default=False)

    Record raw data in dataobject format (e.g. for debugging).

  • WriteWrongHits (bool, default=False)

    Record wrong hits (e.g. for debugging).

  • keepEvenPackages (bool, default=False)

    Keep packages that have even length normally indicating that data was corrupted

  • outputKLMDigitsName (str, default=’’)

    Name of KLMDigit store array.

MCMatcherKLMClusters

Module for MC matching for KLM clusters.

Package

klm

Library

libMCMatcherKLMClusters.so

Parameters
  • Hit2dRelations (bool, default=False)

    Add also relations for BKLMHit2d and EKLMHit2d.

13.2. Clusterization

Few words about how a KLMCluster is built starting from BKLMHit2d and EKLMHit2d are more than desirable.

13.3. Muon identification

Muon identification for the extrapolated tracks in KLM uses differences in longitudinal penetration depth and transverse scattering of the extrapolated track. It is handled by the Muid module, that is part of the tracking package of basf2 and proceeds in two steps:

  1. Track extrapolation using the muon hypothesis only;

  2. Likelihood extraction for each of six particle hypothesis: \(\mu\), \(\pi\), \(K\), \(p\), \(d\), \(e\).

The six likelihoods that are assigned to a given track are stored as log-likelihood values in the KLMMuidLikelihood data-object. In the post-reconstruction analysis, the log-likelihood differences may be used to select or reject the muon hypothesis for a give track.

Muid

Identifies muons by extrapolating tracks from CDC to KLM using geant4e

Package

tracking

Library

libmuid.so

13.3.1. Track extrapolation

The extrapolation proceeds step by step through the detector geometry, starting at the outermost point of the reconstructed track’s trajectory and with phase-space coordinates and covariance matrix. Upon crossing a KLM detector layer, the nearest two-dimensional hit -if any- in that layer is considered for association with the track. If the hit is within about \(3.5\sigma\) (where \(\sigma\) is the 2d hit uncertainty) in either of the two local-coordinates directions then it is declared a matching hit and the Kalman filter uses it to adjust the track properties before the next step in extrapolation. At the same time, the Kalman filter’s fit quality (\(\chi^{2}\)) is accumulated for the track.

The extrapolation ends when the kinetic energy falls below a user-defined threshold (nominally 2 MeV) or the track curls inward to a cylindrical radius below the beam pipe one or the tracks escapes from KLM. If the track reached the KLM, it is classified according to how and where the extrapolation ended (stop or exited and in the barrel or the endcap).

13.3.2. Likelihood extraction

The likelihood of having the matched-hit range and transverse-scattering \(\chi^{2}\) distribution is obtained from pre-calculated probability density functions (PDFs). There are separate PDFs for each charged-particle hypothesis and charge and for each extrapolation outcome.

  • The longitudinal-profile PDF value \(P_{L}(\vec{x}; O, l, H)\) for extrapolation ending outcome \(O\) and outermost layer \(l\) and for particle hypothesis \(H \in {\mu^{\pm}, \pi^{\pm}, K^{\pm}, e^{\pm}, p, \bar{p}, d, \bar{d}}\) is sampled according to the measurement vector \(\vec{c}\) given by: (a) the pattern of of all KLM layers touched during the extrapolation (not just the outermost one) and (b) the pattern of matched hits in the touched layers. Sample PDF for exiting tracks are shown in Fig. 13.1 for muons and pions.

  • The transverse-scattering probability density function \(P_{L}(\chi^2, n; D, H)\) for KLM region \(D\) (barrel-only, endcap-only, or overlap) and particle hypothesis \(H\) is sampled according to the measurement of \(\chi^{2}\) from the Kalman filter and the number of degrees of freedom, which is twice the number of matched hits. The muon-hypothesis PDF is very close to the ideal \(\chi^2\) distribution for the given number of degrees of freedom, while the the non-muon hypothesis PDFs are considerably broader for low degrees of freedom. Sample PDFs are shown in Fig. 13.2 for muons and pions.

../../_images/Longitudinal-PDFs-MuonPion.png

Fig. 13.1 Sample longitudinal-profile PDFs for energetic positively-charged muons (top) and pions (bottom), for the barrel (left), forward endcap (middle) and a selected barrel-endcap overlap (right). The purple histogram represents the PDF. Barrel (endcap) layers are numbered 0-14 (15-28).

../../_images/rchisquared-MuonPlus-PionPlus-ndof.png

Fig. 13.2 Sample transverse-profile (reduced \(\chi^{2}\)) distributions for positively charged muons (top) and pions (bottom) for 2, 6 and 10 degrees of freedom. In each panel the red curve is the fit to the upper tail of the histogram, starting at the given cutoff.

The pre-calculated PDFs are stored in our conditions database as payload of the KLMLikelihoodParameters database object.

For each track, the likelihood for a given particle hypothesis is the product of the corresponding longitudinal-profile and transverse-scattering PDF values:

\[L(H; O, l, D, \vec{x}, \chi^{2}, n) = P_{L}(\vec{x}; O, l, H)\cdot P_{T}(\chi^{2}, n; D, H).\]

The natural logarithm of this value is stored in the KLMMuidLikelihood data-object. Then, the six likelihood values are normalized by dividing by their sum and stored in the KLMMuidLikelihood data-object.

13.3.3. Muon Efficiency and Pion Fake Rate

The log-likelihood difference \(\Delta\) is the most powerful discriminator between the competing hypothesis:

\[\Delta = \log(L(\mu^{+}; O, l, D, \vec{x}, \chi^{2}, n)) - \log(L(\pi^{+}; O, l, D, \vec{x}, \chi^{2}, n)).\]

The requirement \(\Delta > \Delta_{min}\) for a user-selected \(\Delta_{min}\) provides the best signal efficiency for the selected background rejection. Log-likelihood differences for true muons and pions are shown in Fig. 13.3 as a function of the track momentum. Choosing a momentum-independent cut on \(\Delta_{min}\) that is positive and non-zero will reject soft muons preferentially, and a similar behavior is seen when choosing a cut that is independent of the polar or azimuthal angles, because the log-likelihood differences are softer in the azimuthal cracks between sectors and in the barrel-endcap overlap region where KLM is thinner.

../../_images/Log-Likelihood-MuonPion.png

Fig. 13.3 Log-likelihood difference between muon and pion hypotheses for true muons (left) and pions (right) as a function of the track momentum in GeV/c. In each plot five features are shown: (1) minimum and maximum values (bounden by the dashed vertical line); (3) the lower and upper quartiles (below or above the rectangular box); (4)the median (the thick horizontal line segment); (5) and the mean (circle).

Muid Likelihoods are constructed by MuidBuilder class.

class MuidBuilder

Build the Muid likelihoods starting from the hit pattern and the transverse scattering in KLM.

Parameters:

  • pdg (int): PDG code of the particle hypothesis.

Muon efficiency and pion fake rate are shown in Fig. 13.4 as a function of momentum, polar angle, and azimuthal angle for three values of the log-likelihood-difference threshold.

../../_images/MuonEff-PionFakeRate.png

Fig. 13.4 Muon efficiency (solid) and pion fake rate scaled by 10 (dashed) for three values of the log-likelihood-difference cut: \(\Delta_{min}\) = 0 (black), 10 (blue), and 20 (red) as a function of momentum (top-left), polar angle (top-right), and azimuthal angle (bottom left). Muon inefficiency as a function of \(\phi\) vs \(\theta\) (bottom right), illustrating the geometric inefficiencies at the sector boundaries and in the vicinity of the solenoid chimney.

13.4. Calibration

This seems the best place to cite our internal note KLM offline calibration.

13.5. Tools

Section for our beautiful tools.

13.5.1. b2klm-create-dqm: Create DQM reference plots

Tool used to generate the KLM DQM reference plots and to mask the (very) hot channels if necessary.

usage: b2klm-create-dqm [-h] -i FILE [FILE ...] [-n EVENTS]
                        [--prepend_gt [GT [GT ...]]]
                        [--append_gt [GT [GT ...]]] [--raw] [--no_mask]
                        [--output_dqm OUTPUT_DQM]

Optional Arguments

-i, --input

input file names; it is possible to use the wildcard “*” to pass multiple files in input

-n, --events

maximum number of events to be processed

--prepend_gt

Global Tags to be prepended

--append_gt

Global Tags to be appended

--raw

flag for raw input files; it must be used if data must be unpacked and reconstructed from scratch

--no_mask

flag for disable masking of (very) hot channels; the masking is disabled for .sroot files, please convert them to .root if this is necessary

--output_dqm

name of the output .root file containing plots with masked channels

13.5.2. b2klm-mask-dqm: Mask very hot channels in DQM reference plots

Tool used to mask the (very) hot channels in KLM DQM reference plots.

usage: b2klm-mask-dqm [-h] --exp EXP_NUMBER --run RUN_NUMBER [-i INPUT_FILE]
                      [-o OUTPUT_FILE] --globaltags GT [GT ...]

Optional Arguments

--exp

experiment number

--run

run number

-i, --input

input file name

-o, --output

output file name

--globaltags

Global Tags to be used