Skip to content

Commit f90268f

Browse files
committed
Add new analysis scripts and update MyZPeak_cfg.py for improved functionality
1 parent 01b3e2a commit f90268f

4 files changed

Lines changed: 132 additions & 8 deletions

File tree

episodes/files/ZPeakAnalysis.zip

2.28 KB
Binary file not shown.
Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
1+
12
import FWCore.ParameterSet.Config as cms
23
from FWCore.ParameterSet.VarParsing import VarParsing
34

45
options = VarParsing ('analysis')
56

7+
# Adding a custom command line option for Pt
8+
options.inputFiles = "root://cmseos.fnal.gov//store/user/cmsdas/2026/short_exercises/cat/datasets/MINIAODSIM/RunIISummer20UL17MiniAODv2-106X_mc2017_realistic_v9-v2/DYJetsToLL_M-50_TuneCP5_13TeV-amcatnloFXFX-pythia8/2C5565D7-ADE5-2C40-A0E5-BDFCCF40640E.root" #### for cmslpc
9+
#options.inputFiles = "root://xrootd-cms.infn.it//store/group/cat/datasets/MINIAODSIM/RunIISummer20UL17MiniAODv2-106X_mc2017_realistic_v9-v2/DYJetsToLL_M-50_TuneCP5_13TeV-amcatnloFXFX-pythia8/2C5565D7-ADE5-2C40-A0E5-BDFCCF40640E.root" #### for cern
10+
options.register('minPt',
11+
20.0, # default value
12+
VarParsing.multiplicity.singleton,
13+
VarParsing.varType.float,
14+
"Minimum Muon Pt threshold")
15+
16+
options.parseArguments()
17+
618
process = cms.Process("Test")
719

20+
process.load("FWCore.MessageService.MessageLogger_cfi")
21+
process.MessageLogger.cerr.FwkReport.reportEvery = 1000
22+
823
process.source = cms.Source("PoolSource",
9-
fileNames = cms.untracked.vstring (options.inputFiles)
24+
fileNames = cms.untracked.vstring(options.inputFiles)
1025
)
1126

12-
process.MessageLogger = cms.Service("MessageLogger")
1327
process.maxEvents = cms.untracked.PSet(
14-
input = cms.untracked.int32(10000)
28+
input = cms.untracked.int32(options.maxEvents)
1529
)
1630

1731
process.analyzeBasicPat = cms.EDAnalyzer("MyZPeakAnalyzer",
18-
muonSrc = cms.untracked.InputTag("slimmedMuons"),
19-
elecSrc = cms.untracked.InputTag("slimmedElectrons"),
32+
muonSrc = cms.untracked.InputTag("slimmedMuons"),
33+
elecSrc = cms.untracked.InputTag("slimmedElectrons"),
34+
# New parameter added here
35+
minMuonPt = cms.double(options.minPt)
2036
)
2137

2238
process.TFileService = cms.Service("TFileService",
23-
fileName = cms.string('myZPeak.root')
24-
)
39+
fileName = cms.string('myZPeak.root')
40+
)
2541

26-
process.p = cms.Path(process.analyzeBasicPat)
42+
process.p = cms.Path(process.analyzeBasicPat)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
import sys
3+
import argparse
4+
5+
def parse_integral_file(filename):
6+
"""Parses the text file and returns a dictionary of {variable: value}."""
7+
data = {}
8+
try:
9+
with open(filename, 'r') as f:
10+
for line in f:
11+
if ':' in line:
12+
parts = line.split(':')
13+
key = parts[0].replace('Integral of ', '').strip()
14+
value = float(parts[1].strip())
15+
data[key] = value
16+
return data
17+
except IOError:
18+
print "Error: File '{0}' not found.".format(filename)
19+
sys.exit(1)
20+
except Exception as e:
21+
print "Error parsing '{0}': {1}".format(filename, e)
22+
sys.exit(1)
23+
24+
def compare(file1, file2, tolerance=1e-6):
25+
data1 = parse_integral_file(file1)
26+
data2 = parse_integral_file(file2)
27+
28+
all_keys = set(data1.keys()).union(set(data2.keys()))
29+
match = True
30+
31+
print "{0:<20} | {1:<15} | {2:<15} | {3}".format('Variable', 'File 1', 'File 2', 'Status')
32+
print "-" * 70
33+
34+
for key in sorted(all_keys):
35+
val1 = data1.get(key, None)
36+
val2 = data2.get(key, None)
37+
38+
if val1 is None or val2 is None:
39+
status = "MISSING"
40+
match = False
41+
elif abs(val1 - val2) <= tolerance:
42+
status = "PASS"
43+
else:
44+
status = "FAIL"
45+
match = False
46+
47+
print "{0:<20} | {1:<15} | {2:<15} | {3}".format(key, str(val1), str(val2), status)
48+
49+
return match
50+
51+
if __name__ == "__main__":
52+
parser = argparse.ArgumentParser(description="Compare CMSSW integral outputs.")
53+
parser.add_argument("file1", help="First txt file (reference)")
54+
parser.add_argument("file2", help="Second txt file (new run)")
55+
args = parser.parse_args()
56+
57+
if compare(args.file1, args.file2):
58+
print "\nSUCCESS: The files match."
59+
sys.exit(0)
60+
else:
61+
print "\nFAILURE: Differences detected between the runs."
62+
sys.exit(1)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env python
2+
import ROOT
3+
import sys
4+
5+
# Define the input and output filenames
6+
input_file = 'myZPeak.root'
7+
output_txt = 'number_of_events.txt'
8+
9+
# Open the ROOT file
10+
f = ROOT.TFile.Open(input_file)
11+
if not f or f.IsZombie():
12+
print "Error: Could not open {0}".format(input_file)
13+
sys.exit(1)
14+
15+
# In TFileService, histograms are usually inside a directory
16+
# named after the module label in your python config.
17+
# Based on your config, the label is 'analyzeBasicPat'
18+
dir_name = "analyzeBasicPat"
19+
hist_dir = f.Get(dir_name)
20+
21+
if not hist_dir:
22+
print "Error: Directory {0} not found in {1}".format(dir_name, input_file)
23+
f.ls() # List contents to help debugging
24+
sys.exit(1)
25+
26+
# Retrieve the histograms
27+
h_muonMult = hist_dir.Get("muonMult")
28+
h_eleMult = hist_dir.Get("eleMult")
29+
h_mumuMass = hist_dir.Get("mumuMass")
30+
31+
# Calculate integrals
32+
# Integral() returns the sum of bin contents (excluding under/overflow by default)
33+
muon_integral = h_muonMult.Integral()
34+
ele_integral = h_eleMult.Integral()
35+
mumuMass_integral = h_mumuMass.Integral()
36+
37+
# Write to a text file
38+
with open(output_txt, 'w') as f_out:
39+
f_out.write("muonMult: {0}\n".format(muon_integral))
40+
f_out.write("eleMult: {0}\n".format(ele_integral))
41+
f_out.write("mumuMass: {0}\n".format(mumuMass_integral))
42+
43+
print "Successfully wrote integrals to {0}".format(output_txt)
44+
45+
# Close ROOT file
46+
f.Close()

0 commit comments

Comments
 (0)