Skip to content

FNALLPC/MuonDAS2025

 
 

Repository files navigation

Muon Short Exercise 2025

Facilitators

  • Christina Wang
  • Michael Carrigan
  • Chris Cosby
  • Beren Ozek
  • Daniel Wilbern

This tutorial is forked from the Muon HATS offered in 2024: https://github.com/JanFSchulte/MuonHATS

Setup Environment

This exercise is tested at in CMSLPC EL9. In general, it is expected to run where the following requirements are fulfilled:

  • python3
  • uproot
  • awkward
  • ROOT
  • NumPy
  • matplotlib
  • scipy
  • Jupyter Notebook
  • coffea
  • boost

However, the input files used in the exercises are specific to the LPC and will need to be replaced when running somewhere else.

Additional details

Setup on CMSLPC

To start the short exercise, open a terminal/console, connect to cmslpc-el9 and prepare your working area:

kinit username@FNAL.GOV
ssh -L localhost:8888:localhost:8888 <YOUR USERNAME>@cmslpc-el9.fnal.gov

If you haven't done it yet, go to your nobackup area (/uscms_data/d3/<YOUR USERNAME>/) and create a folder for the CMSDAS exercises. Once you are there you can setup the CMSSW environment and clone our repository:

git clone git@github.com:FNALLPC/MuonDAS2025.git
cd MuonDAS2025

The following commands one has to do it everytime you log in into a new session. They load the environment and the packages needed for the exercises and open a jupyter notebook:

source /cvmfs/sft.cern.ch/lcg/views/LCG_105/x86_64-el9-gcc11-opt/setup.sh
jupyter notebook --no-browser --port=8888 --ip 127.0.0.1

Note that the port number 8888 needs to match the port number you log-in to cmslpc. If someone has taken the 8888 port on the cmslpc node, you will need to use another one.

If these two lines are running sucessfully, you should see something like this:

[I 16:02:17.479 NotebookApp] Serving notebooks from local directory: /uscms_data/d3/kkwok/cmsdas/MDS_Ex/MDS_CMSDAS
[I 16:02:17.480 NotebookApp] Jupyter Notebook 6.4.0 is running at:
[I 16:02:17.480 NotebookApp] http://127.0.0.1:8888/?token=6aaf053d114b42696b20bc6df83c1c9078e1253a91cce3b3
[I 16:02:17.480 NotebookApp]  or http://127.0.0.1:8888/?token=6aaf053d114b42696b20bc6df83c1c9078e1253a91cce3b3
[I 16:02:17.480 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 16:02:17.516 NotebookApp] 
    
    To access the notebook, open this file in a browser:
        file:///uscms/homes/k/kkwok/.local/share/jupyter/runtime/nbserver-26071-open.html
    Or copy and paste one of these URLs:
        http://127.0.0.1:8888/?token=6aaf053d114b42696b20bc6df83c1c9078e1253a91cce3b3
     or http://127.0.0.1:8888/?token=6aaf053d114b42696b20bc6df83c1c9078e1253a91cce3b3

Copy and paste one of the last two urls in your favorite browser and now you can continue with Exercise-1-Introduction.ipynb

Useful tips

Since we launch jupyter server frequently, you can make an alias for that command in your ~/.bashrc file

alias sourcelcg='source /cvmfs/sft.cern.ch/lcg/views/LCG_105/x86_64-el9-gcc11-opt/setup.sh'
alias launchJupyter='jupyter notebook --no-browser --port=8888 --ip 127.0.0.1'

then you can just do

sourcelcg
launchJupyter

Introduction: General information on muons in CMS

Muons in CMS are maintained and supported by the Muon POG (Twiki). This group is responsible for the triggering, reconstruction, and identification of muons from the detector signals. The muon detectors, their maintainance and calibration, are the responsibility of the detector projects and Muon DPG. Muons in the L1 trigger are responsibility of the L1 DPG.

For analysts, the best entry point when looking for information about muons in CMS is currently this Twiki page, which contains links to the relevant recommendations. The muon contact of your PAG is your first point of contact for questions about muons, the names are listed on this page as well. Further questions, especially of technical nature, can be asked on CMS Talk. In urgent cases or to request presentations in the one of the POG meetings, contact the POG conveners at cms-phys-conveners-MUO@cern.ch.

Information about muon selections can be found on this Twiki page (still to be migrated to a Run 3 version). Efficiencies for standard use cases are provided by the POG, but if custom selections are used, analysts need to derive them themselves, for example using the Tag & Probe tools described here.

Exercise 1: Introduction, muon object, main variables

In this exercise we will get familiar with the muon objects in a nanoAOD file. We will mostly use a NANOAODSIM file, containing simulated Drell–Yan dimuon events generated at NLO with the program MadGraph.

Now please open Exercise-1-Introduction.ipynb. and follow the instructions in the notebook, run and modify the code. In this exercise, we will see how to interact with the NanoAOD content directly, using uproot and awkward arrays. In the following exercises, we will use the coffea framework instead as a higher-level interface to make our life easier.

After going through the notebook, you should learn the following points.

  • how to explore a nanoAOD using uproot
  • what muon variables are stored in nanoAOD
  • how to do some quick selection using awkward array
  • how to perform deltaR matching between generated muons and reconstructed muons, HLT muons and reconstructed muons

Please try to solve the questions posted in the notebook. Answers can be found in the solutions folder.

Exercise 2: Muon momentum scale and resolution corrections

The measurement of the transverse momentum of muons is sensitive to several detector conditions:

  • the alignment of the tracker and of the muon chambers
  • the composition and distribution of the material inside the tracking volume
  • the knowledge of the magnetic field inside and outside the solenoid volume.

All these conditions affect differently the momentum measurement and can produce biases. In particular, the detector misalignment produces a relative bias that generally increases linearly with the momentum. For this reason it is extremely important to have an accurate knowledge of the tracker and muon spectrometer alignment, and a detailed mapping of the detector material and of the magnetic field. Residual biases can be corrected a posteriori, using calibration techniques that generally exploit data from very well-known processes, such as J/ψ→μμ or Z→μμ decays.

In this exercise we will examine the effects produced by these biases in the momentum measurement and we will use correction factors to mitigate them.

Now please open Exercise-2-Muon-momentum-scale-and-resolution-corrections.ipynb. Please follow the instructions on the notebook, run and modify the code. After going through the notebook, you should learn the following points.

  • basic steps to plot the Z mass
  • how to perform fit using root with various functions
  • what is mass resolution and what is transverse momentum resolution, how they are related
  • how to perform a momentum scale correction

Please try to solve the questions posted in the notebook, answers are stored in the solutions folder.

Exercise 3: Muon identification and isolation

In the previous exercises, we applied cuts on various quantities in muon object without understanding what they were or why we were imposing the suggested requirements. In this exercise, we will build on the discussion in the introduction and the practice with the nanoAOD in the previous exercise to analyze the main properties and quality variables of muon tracks and how they can be used to identify muons from different sources. We will use three seperate NANOAODSIM files, containing simulated Drell–Yan, top-pair, and QCD multijet events:

Step 1: Isolation variables

To better understand the selection criteria, it is useful to classify each muon according to how it was produced:

  • prompt, i.e. from the decay of a W or Z boson or from a τ lepton produced in the hard proton-proton interaction
  • heavy flavor decay, i.e. from the decay of a b-quark or c-quark hadron
  • light flavor decay, i.e. from the decay of a light-quark hadron, such as a pion or a kaon
  • fake muons, such as punch-through or matching of random tracks and muon segments.

In order to isolate each source of muons, we put cut on various variables. Below are variables commonly used for those cuts; please note that the presented way to access them is used in miniAOD.

  • whether the muon is a global muon, i.e. it was reconstructed with a combined fit of tracker and muon chambers measurements muon->isGlobalMuon()
  • whether the muon is a tracker muon, i.e. it was identified by geometrically matching an inner track with segments in the muon chambers muon->isTrackerMuon()
  • Normalized χ2 of the global track fit if(muon->isGlobalMuon()) muon->globalTrack()->normalizedChi2()
  • Number of muon chamber hits included in the global-muon track fit if(muon->isGlobalMuon()) muon->globalTrack()->hitPattern().numberOfValidMuonHits()
  • Number of muon stations with matched segments muon->numberOfMatchedStations()
  • Number of hits in the pixel detector muon->innerTrack()->hitPattern().numberOfValidPixelHits()
  • Number of hits in the tracker layers muon->innerTrack()->hitPattern().trackerLayersWithMeasurement()
  • Transverse impact parameter of the track with respect to the vertex from which the muon originated muon->muonBestTrack()->dxy(firstGoodVertex->position())
  • Isolation based on the sum of pT of charged-hadron PFCandidates from the leading primary vertex in the event, in a cone of ΔR < 0.4 around the muon muon->pfIsolationR04().sumChargedHadronPt
  • Isolation calculated with neutral-hadron PFCandidates in a cone of ΔR < 0.4 around the muon muon->pfIsolationR04().sumNeutralHadronEt
  • Isolation calculated with photon PFCandidates in a cone of ΔR < 0.4 around the muon muon->pfIsolationR04().sumPhotonEt
  • Isolation calculated with all charged particles in a cone of ΔR < 0.4 around the muon, but not from the leading primary vertex (i.e. pileup contribution to the isolation sum) muon->pfIsolationR04().sumPUPt
  • PF-based combined relative isolation, Δβ-corrected for pileup (muon->pfIsolationR04().sumChargedHadronPt + max(0., mu->pfIsolationR04().sumNeutralHadronEt + mu->pfIsolationR04().sumPhotonEt - 0.5*mu->pfIsolationR04().sumPUPt)) / muon->pt()
  • Tracker-based relative isolation muon->isolationR03().sumPt / muon->pt()

In the nanoAOD , the following variables can be found:

Whether the muon is a global muon, i.e. it was reconstructed with a combined fit of tracker and muon chambers measurements
    `Muon_isGlobal` 
Whether the muon is a tracker muon, i.e. it was identified by geometrically matching an inner track with segments in the muon chambers
    `Muon_isTracker` 
Number of muon stations with matched segments
    `Muon_nStations` 
Number of hits in the tracker layers
    `Muon_nTrackerLayers`
Transverse impact parameter of the track with respect to the vertex from which the muon originated
    `Muon_dxy`
PF-based combined relative isolation, Δβ-corrected for pileup
    `Muon_pfRelIso04_all` 
Tracker-based relative isolation
    `Muon_tkRelIso` 

Now, please open Exercise 3 and go to step 1. Please follow the instructions on the notebook, run and modify the code. Please try to solve the questions posted in the notebook, answers are stored in solutions folder.

Step 2: Standard muon definitions in CMS

The CMS Muon Physics Object Group (MUO POG) takes care of everything that concerns muon reconstruction, identification, high-level triggering, performance evaluation and monitoring, corrections, use in physics analysis, etc. Among other tasks, it develops and maintains a number of standard identification and isolation criteria, which are broadly used in analysis across all CMS. The full list of official definitions can be found on this Twiki page page. Here you can find a summary of the most common criteria. These definitions are conveniently implemented as selectors for reco::Muon objects in the MuonSelectors class, as well as functions in the pat::Muon class.

  • Loose Muons
bool pat::Muon::isLooseMuon()
bool muon::isLooseMuon(const reco::Muon& muon) {
    return muon.isPFMuon() && (muon.isGlobalMuon() || muon.isTrackerMuon());
}
  • Medium Muons
bool pat::Muon::isMediumMuon()
bool muon::isMediumMuon(const reco::Muon& muon) {
    if( !( isLooseMuon(muon) && muon.innerTrack()->validFraction() > 0.8 )) return false;

    bool goodGlb = muon.isGlobalMuon() &&
        muon.globalTrack()->normalizedChi2() < 3. &&
        muon.combinedQuality().chi2LocalPosition < 12. &&
        muon.combinedQuality().trkKink < 20.;

    return (segmentCompatibility(muon) > (goodGlb ? 0.303 : 0.451));
}
  • Tight Muons
bool pat::Muon::isTightMuon(const reco::Vertex& vtx)
bool muon::isTightMuon(const reco::Muon& muon, const reco::Vertex& vtx) {
    if(!muon.isPFMuon() || !muon.isGlobalMuon()) return false;
    bool muID = muon.isGlobalMuon() && muon.globalTrack()->normalizedChi2() < 10 && muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 && muon.numberOfMatchedStations() > 1;  
    bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 && muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
    bool ip = fabs(muon.muonBestTrack()->dz(vertex->position())) < 0.5 && fabs(muon.muonBestTrack()->dxy(vertex->position())) < 0.2;
    return muID && hits && ip;
}
  • Soft Muons
bool pat::Muon::isSoftMuon(const reco::Vertex& vtx)
bool muon::isSoftMuon(const reco::Muon& muon, const reco::Vertex& vtx) {
    bool muID = muon::isGoodMuon(muon, TMOneStationTight);
    if(!muID) return false;

    bool layers = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
        muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
    bool ishighq = muon.innerTrack()-&gt;quality(reco::Track::highPurity);
    bool ip = fabs(muon.innerTrack()->dxy(vertex->position())) < 0.3 && fabs(muon.innerTrack()->dz(vertex->position())) < 20.;
  

    return layers && ip && ishighq;
}
  • HighPt Muons
bool pat::Muon::isHighPtMuon(const reco::Vertex& vtx)
bool muon::isHighPtMuon(const reco::Muon& muon, const reco::Vertex& vtx){
    bool muID = muon.isGlobalMuon() && muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 && (muon.numberOfMatchedStations() > 1);
    if(!muID) return false;

    bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
        muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
    bool momQuality = muon.tunePMuonBestTrack()->ptError()/muon.tunePMuonBestTrack()->pt() < 0.3;
    bool ip = fabs(muon.innerTrack()->dz(vertex->position())) < 0.5	&& fabs(muon.innerTrack()->dxy(vertex->position())) < 0.2;

    return muID && hits && momQuality && ip;
}

Now, please open Exercise 3 and go to step 2. Please try to solve the questions posted in the notebook, answers are stored in solutions folder.

Step 3: Muon isolation

Let's now take a detailed look at the isolation variables mentioned at the beginning of Exercise 3. The most common muon isolation algorithm in CMS makes use of the PF candidates found in a region of ΔR < 0.4 around the muon track:

mu->pfIsolationR04().sumChargedHadronPt   // pT sum of charged hadrons from the main primary vertex of the event
mu->pfIsolationR04().sumNeutralHadronEt   // pT sum of neutral hadrons
mu->pfIsolationR04().sumPhotonEt          // pT sum of photons

In order to exploit the full-detector information, these variables can be combined in a single isolation variable:

const reco::MuonPFIsolation &pfR04 = mu->pfIsolationR04();
double combRelIso = (pfR04.sumChargedHadronPt + pfR04.sumNeutralHadronEt + pfR04.sumPhotonE) / mu->pt();   // combined relative isolation

The combined isolation turns out to perform better than the individual components separately in terms of efficiency vs background rejection. Note that for neutral particles (photons and neutral hadrons) it is impossible to determine the vertex they originated from, since they don't have a track. Therefore neutral particles from pileup vertices contribute to the pT sum, and the performance of the combined isolation results to be strongly dependent on the pileup level. Corrections are available to mitigate such effect. The most common in CMS is called "Δβ correction": it estimates the ΣpT of neutral particles coming from pileup vertices using the ΣpT of charged particles from pileup vertices (mu->pfIsolationR04().sumPUPt), and the ratio of neutral-to-charged particles expected in LHC proton-proton collisions. From simulation studies, this ratio results to be about 0.5.

We can now define a Δβ-corrected combined relative isolation, less sensitive to the number of pileup vertices:

const reco::MuonPFIsolation &pfR04 = mu->pfIsolationR04();
double corrCombRelIso = (pfR04.sumChargedHadronPt + std::max(0.0, pfR04.sumNeutralHadronEt + pfR04.sumPhotonEt - 0.5*pfR04.sumPUPt)) / mu->pt();

All the variables described above can be find in a minAOD file. In nanoAOD, the Δβ-corrected combined relative isolation is already calculated for you. It is stored as Muon_pfRelIso04_all.

Now, please open Exercise 3 and go to step 3. Please try to solve the questions posted in the notebook, answers are stored in solutions folder.

Exercise 4: Muon efficiency

Tag-and-Probe is a data-driven technique used to calculate lepton reconstruction, identification, and trigger efficiencies. This technique uses narrow dilepton resonances, such as Z (for muons with relatively high pT) or J/ψ (for muons with lower pT). Almost-unbiased estimates of the efficiencies can be obtained at the different stages of muon trigger and offline reconstruction. Events are selected with strict requirements on one muon (the tag), and with a more relaxed selection on the other muon (the probe), such that the probe muon can be used to measure the efficiency in question without large biases. The fraction of probe muons that pass the selection under study gives an estimate of its efficiency. The invariant mass of the tag-probe pair is used to select Z→μμ or J/ψ→μμ events.

The Tag-and-Probe technique is generally used to measure and compare efficiencies in data and in MC simulation, and thus to compute a correction scale factor that can be applied to MC events to match the efficiency observed in data. These scale factors are typically determined as functions of pT and η. If necessary, their dependence on other kinematic variables can be investigated too — e.g. vs the number of vertices, in case of strong pileup dependence. In some cases, customized scale factors are necessary for some analyses, depending on their specific trigger and offline thresholds.

Despite the tight selection on the tag muon and the invariant mass constraints, the selected Z→μμ or J/ψ→μμ sample generally contains background events, which appear as a nonresonant continuum underneath the resonance peak. Therefore the background must be subtracted, to ensure that the efficiency is measured with signal muons only. This can be achieved by fitting the invariant mass spectrum to signal + background shapes (e.g. analytical functions or MC templates). Finding proper functions or templates for signal and background is often the most challenging part of the process.

The total lepton efficiency is generally factorized in multiple steps as follows: total lepton efficiency = (tracking) × (reconstruction/tracking) × (ID/reconstruction) × (isolation/ID) × (trigger/isolation) In each efficiency step, the denominator determines the selection of the probe. In the last steps (in part. isolation and trigger), the probe selection is tighter and, therefore, the background level is quite low and the background subtraction is generally easier — or not even needed, in some cases. In this exercise, you will measure efficiencies using simulated Z→μμ events.

Since you are using a pure Z sample, you won't need background subtraction nor fitting. The efficiency will simply be computed by counting probes before and after the selection under study.

You will start by computing "true" efficiencies using the generator-level information. This will be your reference efficiencies. Next, you will implement a simple tag-and-probe algorithm to measure the efficiencies with a data-driven approach, and you will compare your results to the "true" efficiencies. Finally, you will try to use the same algorithm on a real single-muon data sample, taken from the 2022F CMS data.

Detailed instructions are already posted in Exercise-4-Muon-Efficiencies.ipynb. Now please open Exercise-4-Muon-Efficiencies.ipynb. Please follow the instructions on the notebook, run and modify the code. Please try to solve the questions posted in the notebook, answers are stored in solutions folder.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Jupyter Notebook 99.6%
  • Other 0.4%