Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
a61a72d
remove files that are now in DrawHits
wa01 Nov 25, 2025
56e97dd
logZ option
wa01 Dec 1, 2025
7f0de31
utility for histograms
wa01 Dec 2, 2025
2b8128b
some more options for fits
wa01 Dec 2, 2025
567be62
cosmetics for res mean/width in 2d
wa01 Dec 2, 2025
14b0a34
change match to classical if elif statement to stay compatible with o…
wa01 Dec 2, 2025
5fc9c88
cosmetics
wa01 Dec 3, 2025
2fbcf3e
add histograms residuals (vs. pos on strip) vs. angle / cluster size
wa01 Dec 3, 2025
331c60a
define quantiles from cumulative histo of residuals via spline
wa01 Dec 3, 2025
8bde1d1
mainly cosmetics
wa01 Dec 4, 2025
0bd5fbe
style
wa01 Dec 4, 2025
2e2288e
tuning of quantile / width calculation
wa01 Dec 5, 2025
446a242
add efficiency as f(dx/dz)
wa01 Dec 5, 2025
e6572f9
adding result of fit
wa01 Dec 11, 2025
53950fa
adding result of fit
wa01 Dec 11, 2025
4ca6fdb
update to fitRes
wa01 Jan 9, 2026
d83c0b7
Merge branch 'HephyAnalysisSW:main' into main
wa01 Jan 9, 2026
22f0207
building config file for use with Angs Plotter scripts
wa01 Jan 12, 2026
081b040
started implementing Plotter config file
wa01 Jan 12, 2026
edaba10
implement RDF within DrawHits
wa01 Jan 14, 2026
5a146c4
tested define histo1D
wa01 Jan 14, 2026
60b3a4a
tested define histo1D
wa01 Jan 14, 2026
11d9040
add helper for showing histogram definitions
wa01 Jan 14, 2026
0756c0b
tested RDF with 2D
wa01 Jan 14, 2026
3b2b762
tested RDF with Profile1D
wa01 Jan 14, 2026
3808aa0
tested RDF with 3D
wa01 Jan 14, 2026
a41b9de
working version for all histograms in drawHitsTmpRDF.yaml
wa01 Jan 14, 2026
c4c69aa
remove obsolete / dbg code
wa01 Jan 14, 2026
a2bb11e
hide Define for variable+mask within a wrapper around RDataFrame
wa01 Jan 15, 2026
a82c154
prepare also drawHitsRes config for RDF
wa01 Jan 15, 2026
5d79e94
adding histograms for rechit multiplicity
wa01 Jan 27, 2026
61652bd
adding histograms for rechit multiplicity
wa01 Jan 27, 2026
6d9af78
add histograms of # RecHits / SimHit
wa01 Jan 29, 2026
b760418
add #simtracks to RecHitInfo
wa01 Jan 29, 2026
da11501
small bug fix / optimisations in SimHit / RecHit match
wa01 Jan 29, 2026
b3951fa
some debug code for RecHits
wa01 Feb 9, 2026
75f2e11
small changes in input file list in cfgs
wa01 Feb 9, 2026
975ea71
more flexible access to SimHit collections
wa01 Feb 9, 2026
aa38e7d
create common helper classes for SimHitInfo and RecHitInfo
wa01 Feb 11, 2026
cc62282
moved functionality from SimHitInfo to CommonHitInfo
wa01 Feb 11, 2026
803e5c4
start to move functionality from RecHitInfo to CommonHitInfo
wa01 Feb 11, 2026
7dd0f35
adapt mu cfg file
wa01 Feb 12, 2026
2ca9421
debug information
wa01 Feb 12, 2026
3b2e7d2
cosmetic mod in tt cfg
wa01 Feb 13, 2026
e78aeef
preparing common sim / rechit matching
wa01 Feb 13, 2026
e08a4be
moving to ClusterSimTracks class
wa01 Feb 19, 2026
e766cd2
extra dbg info
wa01 Mar 12, 2026
d7546ed
remove by channel cache from ClusterSimTracks
wa01 Mar 13, 2026
fca2da2
fix use of ClusterSimTracks
wa01 Mar 17, 2026
64f2079
fix fitRes for 1D histograms
wa01 Apr 1, 2026
eabac68
added some histogram fitting to drawHitsRDF
wa01 Apr 1, 2026
9e979e4
removed debug output in RecHitTreeWA
wa01 Apr 1, 2026
00efbd8
fit all 3 module types at once
wa01 Apr 1, 2026
ba5e1da
adding width summaries for 1D residuals (in progress)
wa01 Apr 2, 2026
2d4c8fd
move to 15_1_0 sample
wa01 Apr 8, 2026
ef5542b
debug statements
wa01 Apr 8, 2026
1b68b08
bug fix in globPt variable and (almost complete) implementation of RD…
wa01 Apr 8, 2026
01d6038
raise exception when trying to fit resolution on 2D histogram
wa01 Apr 8, 2026
e90fb7e
bug fix for definition of tilted sensors
wa01 Apr 8, 2026
4feae17
cosmetics for prob vs. x vs dx/dz histograms
wa01 Apr 8, 2026
4429970
more fixes for RDF for efficiency histograms
wa01 Apr 8, 2026
f06fd29
helper script to extract histogram definitions in text form
wa01 Apr 9, 2026
c93b477
script to compare outputs of histogramConfigsToText.py
wa01 Apr 9, 2026
702c18e
(re-)moving histogram definitions in / between RDF.yaml config files
wa01 Apr 9, 2026
6f810b4
(re-)moving histogram definitions in / between RDF.yaml config files
wa01 Apr 9, 2026
c152b37
(re-)moving histogram definitions in / between RDF.yaml config files
wa01 Apr 9, 2026
d94e3b7
moving histograms between configs
wa01 Apr 10, 2026
6bab327
moving to CMSSW_15_1 sample
wa01 Apr 10, 2026
9b3a2cf
moved remaining eff histograms from Tmp to Eff
wa01 Apr 10, 2026
6bef868
moved remaining res/pull histograms from Tmp to Res
wa01 Apr 10, 2026
0d819a0
moved remaining res/pull histograms from Tmp to Res
wa01 Apr 10, 2026
35cacd3
moving to CMSSW_15_1 sample
wa01 Apr 10, 2026
15e3f19
intermediate version
wa01 Apr 27, 2026
8e7597b
updates to fitting tools
wa01 Apr 28, 2026
da0a027
debugging
wa01 Apr 28, 2026
17f4b7f
add arguments
wa01 Apr 29, 2026
7c5281d
debugging
wa01 Apr 30, 2026
e642b88
separate file for FitHistogram class
wa01 May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
438 changes: 438 additions & 0 deletions DrawHits/FitHistogram.py

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions DrawHits/compareHistogramConfigs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import sys,os
import subprocess
import csv

allFiles = { }
allDirs = set()
#
# loop over directories with text files
#
for d in sys.argv[1:]:
#
# assume last part of directory name is unique
#
dn = os.path.basename(os.path.normpath(d))
assert not dn in allDirs
allDirs.add(dn)
#
# retrieve cksums for all text files
#
filePattern = os.path.join(d,"*.txt")
result = subprocess.run("cksum "+filePattern, text=True, capture_output=True, shell=True)
result.check_returncode()
#
# loop over output
#
for l in result.stdout.split(chr(10)):
if l=="":
continue
#
# decode output line
#
fields = l.split()
assert len(fields)==3
cksum = int(fields[0])
size = int(fields[1])
name = os.path.splitext(os.path.basename(fields[2]))[0]
#
# store result by name ( directory, cksum, and size )
#
if not name in allFiles:
allFiles[name] = [ ( dn, cksum, size ) ]
else:
allFiles[name].append( ( dn, cksum, size ) )
#
allDirs = sorted(allDirs)
#
# write result to output file
#
with open("compareHistogramConfigs.csv","wt") as csvFile:
csvwriter = csv.writer(csvFile)
# header row 1
row = [ "Name" ]
for d in allDirs:
row.extend([ d, "", "" ])
row.append("#ids")
row.append("#dirs")
csvwriter.writerow(row)
# header row 2
row = [ "" ]
for d in allDirs:
row.extend([ "size", "cksum", "id" ])
row.append("")
row.append("")
csvwriter.writerow(row)
#
# loop over all definitions
#
for n in sorted(allFiles.keys()):
#
row = [ n ]
#
# create list of all unique file ids (defined by size and cksum)
#
cksums = set([ ( x[2], x[1] ) for x in allFiles[n] ])
cksums = sorted(cksums)
#
# add information for each directory
#
for dn in allDirs:
rowExt = [ "", "", "" ]
#
# (try to) find directory in list for this name
#
for d,c,s in allFiles[n]:
if d==dn:
idx = cksums.index((s,c))
rowExt = [s,c,idx]
break
row.extend(rowExt)
#
row.append(len(cksums))
row.append(len(allFiles[n]))
csvwriter.writerow(row)
csvFile.close()

66 changes: 60 additions & 6 deletions DrawHits/drawHits.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ def fillHistoByDef(tree,hDef,extraCuts):
if hDef.vetoMType(mType):
continue
is1D = hDef.getParameter('yNbins',mType)==None
is2D = hDef.getParameter('yNbins',mType)!=None and hDef.getParameter('zNbins',mType)==None
is3D = hDef.getParameter('yNbins',mType)!=None and hDef.getParameter('zNbins',mType)!=None
isProfile = hDef.getParameter('profile',mType)!=None and hDef.getParameter('profile',mType)
effCuts = hDef.getParameter('effCuts',mType)
variable = hDef.getParameter('variable',mType)
Expand All @@ -278,6 +280,7 @@ def fillHistoByDef(tree,hDef,extraCuts):
tree.Project(hName+"_2",variable, \
cutString(extraCuts,hDef.getParameter('baseCuts',mType),"moduleType=="+str(mType),effCuts))
histos[mType][3] = ROOT.TEfficiency(histos[mType][1],histos[mType][0])
histos[mType][3].SetMarkerStyle(20)
else:
# always keep final histogram in 4th position
histos[mType][3] = histos[mType][0]
Expand All @@ -290,7 +293,7 @@ def fillHistoByDef(tree,hDef,extraCuts):
cutString(extraCuts,hDef.getParameter('baseCuts',mType),"moduleType=="+str(mType)))
# always keep final histogram in 4th position
histos[mType][3] = histos[mType][0]
else:
elif is2D:
nby = hDef.getParameter('yNbins',mType)
ymin = hDef.getParameter('yMin',mType)
ymax = hDef.getParameter('yMax',mType)
Expand All @@ -310,13 +313,27 @@ def fillHistoByDef(tree,hDef,extraCuts):
else:
# always keep final histogram in 4th position
histos[mType][3] = histos[mType][0]
elif is3D:
nby = hDef.getParameter('yNbins',mType)
ymin = hDef.getParameter('yMin',mType)
ymax = hDef.getParameter('yMax',mType)
nbz = hDef.getParameter('zNbins',mType)
zmin = hDef.getParameter('zMin',mType)
zmax = hDef.getParameter('zMax',mType)
histos[mType] = [ ROOT.TH3F(hName+"_1",hName+"_1",nbx,xmin,xmax,nby,ymin,ymax,nbz,zmin,zmax), \
None, None, None ]
tree.Project(hName+"_1",variable, \
cutString(extraCuts,hDef.getParameter('baseCuts',mType),"moduleType=="+str(mType)))
assert effCuts==None
# always keep final histogram in 4th position
histos[mType][3] = histos[mType][0]
#print("Ending for ",hDef.name,hName,hTitle)

savedDir.cd()
return histos


def drawHistoByDef(histos,hDef,logY=False,same=False):
def drawHistoByDef(histos,hDef,logY=False,logZ=False,same=False):
result = { 'cnv' : None, 'histos' : histos, 'pave' : None }

savedDir = ROOT.gDirectory
Expand Down Expand Up @@ -344,6 +361,8 @@ def drawHistoByDef(histos,hDef,logY=False,same=False):
if hDef.vetoMType(mType):
continue
is1D = hDef.getParameter('yNbins',mType)==None
is2D = hDef.getParameter('yNbins',mType)!=None and hDef.getParameter('zNbins',mType)==None
is3D = hDef.getParameter('yNbins',mType)!=None and hDef.getParameter('zNbins',mType)!=None
isProfile = hDef.getParameter('profile',mType)!=None and hDef.getParameter('profile',mType)
effCuts = hDef.getParameter('effCuts',mType)
variable = hDef.getParameter('variable',mType)
Expand All @@ -362,6 +381,7 @@ def drawHistoByDef(histos,hDef,logY=False,same=False):
xmax = hDef.getParameter('xMax',mType)

ytitle = hDef.getParameter('yTitle',mType) if hDef.getParameter('yTitle',mType) else ""
ztitle = hDef.getParameter('zTitle',mType) if hDef.getParameter('zTitle',mType) else ""
if is1D and ( not isProfile ):
ymin = hDef.getParameter('yMin',mType) if hDef.getParameter('yMin',mType)!=None else 0.
ymax = hDef.getParameter('yMax',mType) if hDef.getParameter('yMax',mType)!=None else 1.05
Expand All @@ -372,13 +392,16 @@ def drawHistoByDef(histos,hDef,logY=False,same=False):
histos[mType][2].GetXaxis().SetTitle(xtitle)
histos[mType][2].GetYaxis().SetTitle(ytitle)
histos[mType][3] = ROOT.TEfficiency(histos[mType][1],histos[mType][0])
histos[mType][3].SetMarkerSize(0.3)
histos[mType][3].SetMarkerStyle(20)
histos[mType][3].Draw("same Z")
else:
histos[mType][0].SetTitle(hTitle)
histos[mType][0].GetXaxis().SetTitle(xtitle)
histos[mType][0].GetYaxis().SetTitle(ytitle)
histos[mType][0].Draw("same" if same else "")
fitFunc = hDef.getParameter('fit')
if fitFunc!=None:
histos[mType][0].Fit(fitFunc,"Q","same")
elif isProfile:
histos[mType][0].SetTitle(hTitle)
histos[mType][0].GetXaxis().SetTitle(xtitle)
Expand All @@ -387,7 +410,7 @@ def drawHistoByDef(histos,hDef,logY=False,same=False):
#histos[mType][0].SetFillColor(ROOT.TColor.GetColorBright(ROOT.kGray))
#histos[mType][0].SetFillColor(ROOT.kGray)
histos[mType][0].Draw("same" if same else "")
else:
elif is2D:
assert not same
zmin = hDef.getParameter('zMin',mType) if hDef.getParameter('zMin',mType)!=None else 0.
zmax = hDef.getParameter('zMax',mType) if hDef.getParameter('zMax',mType)!=None else 1.05
Expand All @@ -403,8 +426,20 @@ def drawHistoByDef(histos,hDef,logY=False,same=False):
histos[mType][0].GetXaxis().SetTitle(xtitle)
histos[mType][0].GetYaxis().SetTitle(ytitle)
histos[mType][0].Draw("ZCOL")
elif is3D:
assert not same
zmin = hDef.getParameter('zMin',mType) if hDef.getParameter('zMin',mType)!=None else 0.
zmax = hDef.getParameter('zMax',mType) if hDef.getParameter('zMax',mType)!=None else 1.05
assert effCuts==None
histos[mType][0].SetTitle(hTitle)
histos[mType][0].GetXaxis().SetTitle(xtitle)
histos[mType][0].GetYaxis().SetTitle(ytitle)
histos[mType][0].GetZaxis().SetTitle(ztitle)
histos[mType][0].Draw()
if logY or hDef.getParameter('logY',mType):
ROOT.gPad.SetLogy(1)
if is2D and ( logZ or hDef.getParameter('logZ',mType) ):
ROOT.gPad.SetLogz(1)
ROOT.gPad.Update()

#cnv.cd()
Expand Down Expand Up @@ -484,10 +519,13 @@ def addHistogram(varString,cuts,effCuts=None,name='userHist'):
type=str, default='*')
parser.add_argument('--vetoedHistograms', help='comma-separated names of histogram definitions not to be used',
type=str, default='')
parser.add_argument('--logY', help='use log scale', action='store_true', default=False)
parser.add_argument('--logY', help='use log scale for y axis', action='store_true', default=False)
parser.add_argument('--logZ', help='use log scale for z axis', action='store_true', default=False)
parser.add_argument('--printTree', '-p', help='print TTree contents', action='store_true', default=False)
parser.add_argument('--listHistograms', '-l', help='list predefined and selected histograms', \
action='store_true', default=False)
parser.add_argument('--zone', '-z', help='restrict to zone in OT (barrel, tilted, endcap)', type=str, \
choices=['barrel','tilted','endcap'], default=None)
parser.add_argument('file', help='input file', type=str, nargs='+', default=None)
args = parser.parse_args()
outputFormats = [ ]
Expand All @@ -498,6 +536,19 @@ def addHistogram(varString,cuts,effCuts=None,name='userHist'):
fitResiduals = args.fitResiduals.split(",") if args.fitResiduals else [ ]
selectedHistoNames = args.selectedHistograms.split(",")
vetoedHistoNames = args.vetoedHistograms.split(",")
#
# add cut for zone definition?
#
if args.zone=="barrel":
zoneCuts = "detNormal.Rho()>0.99"
elif args.zone=="endcap":
zoneCuts = "detNormal.Rho()<0.01"
elif args.zone=="tilted":
zoneCuts = "detNormal.Rho()>0.05&&detNormal.Rho()<0.095"
else:
zoneCuts = ""
args.cuts = cutString(args.cuts,zoneCuts)

#
# load histogram definitions
#
Expand Down Expand Up @@ -591,14 +642,17 @@ def addHistogram(varString,cuts,effCuts=None,name='userHist'):
for hName in allHDefs.byCanvas[cName]:
print("Processing histogram",hName,"in canvas",cName)
cHistos[hName] = fillHistoByDef(simHitTree,allHDefs.byCanvas[cName][hName],extraCuts)
allObjects.append(drawHistoByDef(cHistos[hName],allHDefs.byCanvas[cName][hName],logY=args.logY,same=same))
allObjects.append(drawHistoByDef(cHistos[hName],allHDefs.byCanvas[cName][hName], \
logY=args.logY,logZ=args.logZ,same=same))
same = True
if args.output!=None:
c = allObjects[-1]['cnv']
#for c in [ x['cnv'] for x in allObjects ]:
basename = os.path.join(args.output,c.GetName())
if args.sampleName!=None:
basename += "_" + args.sampleName
if args.zone!=None:
basename += "_" + args.zone
print(basename)
for fmt in outputFormats:
c.SaveAs(basename+"."+fmt)
Expand Down
Loading