FCCAnalysis plotting error

Dear experts, I’m having some issues running the plotting step of FCCAnalyses. Stage1 & final works fine, but when trying to run the plotting - I get the following error:

----> INFO: Input directory: DarkPhotons/histos/
----> INFO: Output directory: DarkPhotons/Plots/
----> INFO: Output file types to be used: [png]
----> INFO: Integrated luminosity: 1.08e+07 pb-1
----> INFO: Scale factor for signal: 0
----> INFO: Scale factor for background: 0
----> INFO: Signal stacking options to be used for the plots: [nostack]
----> INFO: X-axis scale types to be used for the plots: [lin]
----> INFO: Y-axis scale types to be used for the plots: [lin, log]
----> INFO: Plotting staged analysis plots...
----> INFO:   var: n_RecoMuons     label: DarkPhotons     selection: selNone
----> WARNING: No histograms provided!
                 - plot name: "n_RecoMuons_DarkPhotons_liny"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "n_RecoMuons_DarkPhotons_logy"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "AAAyields_DarkPhotons"
               Continuing...
----> INFO:   var: RecoMuons_InvMass     label: DarkPhotons     selection: selNone
----> WARNING: No histograms provided!
                 - plot name: "RecoMuons_InvMass_DarkPhotons_liny"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "RecoMuons_InvMass_DarkPhotons_logy"
               Continuing...
----> INFO:   var: Leading_jets_invMass     label: DarkPhotons     selection: selNone
----> WARNING: No histograms provided!
                 - plot name: "Leading_jets_invMass_DarkPhotons_liny"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "Leading_jets_invMass_DarkPhotons_logy"
               Continuing...
----> INFO:   var: LeadingJet_pt     label: DarkPhotons     selection: selNone
----> WARNING: No histograms provided!
                 - plot name: "LeadingJet_pt_DarkPhotons_liny"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "LeadingJet_pt_DarkPhotons_logy"
               Continuing...
----> INFO:   var: SubleadingJet_pt     label: DarkPhotons     selection: selNone
----> WARNING: No histograms provided!
                 - plot name: "SubleadingJet_pt_DarkPhotons_liny"
               Continuing...
----> WARNING: No histograms provided!
                 - plot name: "SubleadingJet_pt_DarkPhotons_logy"
               Continuing...

My plotting script looks like the following:

import ROOT

# global parameters
intLumi        = 10.8e+06 #in pb-1

###If scaleSig=0 or scaleBack=0, we don't apply any additional scaling, on top of the normalization to cross section and integrated luminosity, as defined in finalSel.py
###If scaleSig or scaleBack is not defined, plots will be normalized to 1
scaleSig       = 0.
scaleBack      = 0.
ana_tex        = 'e^{+}e^{-} #rightarrow Zh, Z #rightarrow qq, h #rightarrow ZdZd, Zd #rightarrow #mu #mu'
delphesVersion = '3.4.2'
energy         = 240
collider       = 'FCC-ee'
inputDir       = 'DarkPhotons/histos/'
formats        = ['png']
yaxis          = ['lin','log']
stacksig       = ['nostack']
outdir         = 'DarkPhotons/Plots/'
splitLeg       = False

variables = ['n_RecoMuons',
             'RecoMuons_InvMass',
             'Leading_jets_invMass',
             'LeadingJet_pt',
             'SubleadingJet_pt',
]

#Dictionary with the list of selections to be plotted for this analysis. The name of the selections should be the same than in the final selection
selections = {}
selections['DarkPhotons']  = [
    "selNone",
]

extralabel = {}
extralabel['selNone'] = r"No selection"



linestyle = {}
colors = {}
colors['dark_photon_mZd500MeV_e_8.07e-6'] = ROOT.kMagenta-10
colors['dark_photons_mZd380MeV_e_6.7e-7'] = ROOT.kBlue+3

plots = {}
plots['DarkPhotons'] = {
      'signal':{'dark_photon_mZd500MeV_e_8.07e-6':['dark_photon_mZd500MeV_e_8.07e-6'],
                'dark_photons_mZd380MeV_e_6.7e-7':['dark_photons_mZd380MeV_e_6.7e-7'],
                },
        'backgrounds':{
                }
            }

legend = {}
legend['dark_photon_mZd500MeV_e_8.07e-6'] = r'500 MeV, 8.07\times10^{-6}'
legend['dark_photons_mZd380MeV_e_6.7e-7'] = r'380 MeV, 6.7\times10^{-7}'

Am I making any obvious mistakes? I’m also using the preedm4hep version. Thanks :smiley:

Hi @sbenabde,

can you also post the contents of your final stage script?

Best,
Juraj

Hi @jsmiesko!

Here is the final stage script:

#Input directory where the files produced in the pre-selection stages are
inputDir = "DarkPhotons/STAGE1_outputs"

#Output directory where the resulting files will be stored
outputDir = "DarkPhotons/FINAL_output"

#Run over the full statistics from stage1 input file
processList = {
        'dark_photon_mZd500MeV_e_8.07e-6':{},
        'dark_photons_mZd380MeV_e_6.7e-7':{},
        'dark_photons_mZd1200MeV_e_2.12e-6':{},
}
processLabels = {
    # #signals
    'dark_photon_mZd500MeV_e_8.07e-6': r"m$_{Z_D}$ = 500 MeV, $\epsilon$ = 8.07*10$^{-6}$",
    'dark_photons_mZd380MeV_e_6.7e-7': r"m$_{Z_D}$ = 380 MeV, $\epsilon$ = 6.7*10$^{-7}$",
    'dark_photons_mZd1200MeV_e_2.12e-6': r"m$_{Z_D}$ = 1200 MeV, $\epsilon$ = 2.12*10$^{-6}$",
}

#Link to the dictionary that contains all the cross section information etc...
procDict = "FCCee_procDict_winter2023_IDEA.json"

#Expected integrated luminosity
intLumi = 10.8e+06  #pb-1

#Whether to scale to expected integrated luminosity
doScale = False

#Number of threads to use
nCPUS = 4

#Whether to produce ROOT TTrees, default is False
doHistos = True

#Save cut yields and efficiencies in LaTeX table
saveTabular = True

# Save cut yields and efficiencies in JSON file
saveJSON = False

#Dictionary with the list of cuts. The key is the name of the selection that will be added to the output file
cutList = {
    "selNone": "n_RecoMuons >= 0",
    # For event selection
    "Z-mass_jets": "(n_RecoJets >= 2) && (Leading_jets_invMass > 70 && Leading_jets_invMass < 110)",
    "four_muons": "n_RecoMuons >= 4",
    "exactly_four_muons": "n_RecoMuons == 4",
}
cutLabels = {
    "selNone": "Before selection",
    # For event selection
    "Z-mass" : r"$80<m_{Z}<100$ GeV",
    "4_muons" : r"n_RecoMuons >= 4",
    "4_muons" : r"n_RecoMuons = 4",
}

# Dictionary for the output variables/histograms. The key is the name of the
# variable in the output files. "name" is the name of the variable in the input
# file, "title" is the x-axis label of the histogram, "bin" the number of bins
# of the histogram, "xmin" the minimum x-axis value and "xmax" the maximum
# x-axis value.


histoList = {   
    'n_RecoMuons':                  {"name":'n_RecoMuons',               "title": "Number of reco. muons",               "bin":10,  "xmin":0,  "xmax":10 },
    'RecoMuon1_pt':                 {"name":'RecoMuon1_pt',              "title": "Muon1 Pt",                            "bin":100,  "xmin":0, "xmax":200},
    'RecoMuon2_pt':                 {"name":'RecoMuon2_pt',              "title": "Muon2 Pt",                            "bin":100,  "xmin":0, "xmax":200},
    'RecoMuon3_pt':                 {"name":'RecoMuon3_pt',              "title": "Muon3 Pt",                            "bin":100,  "xmin":0, "xmax":200},
    'RecoMuon4_pt':                 {"name":'RecoMuon4_pt',              "title": "Muon4 Pt",                            "bin":100,  "xmin":0, "xmax":200},

    'RecoMuons_InvMass':            {"name":'RecoMuons_InvMass',         "title": "Invariant mass of the Higgs boson",   "bin":100, "xmin":80, "xmax":160},
    "LeadingJet_eta":               {"name":'LeadingJet_eta',            "title": "Leading Jet Eta",                     "bin":100, "xmin":80, "xmax":160},
    "SubleadingJet_eta":            {"name":'SubleadingJet_eta',         "title": "Subleading Jet Eta",                  "bin":100, "xmin":80, "xmax":160},
    'Leading_jets_invMass':         {"name":'Leading_jets_invMass',      "title": "Invariant mass of the Z boson",       "bin":100, "xmin":20, "xmax":300},
    'Leading_jet_invMass':          {"name":'Leading_jet_invMass',       "title": "Invariant mass of the leading jet",   "bin":100, "xmin":20, "xmax":300},
    'Subleading_jet_invMass':       {"name":'Subleading_jet_invMass',    "title": "Invariant mass of the subleading jet","bin":100, "xmin":20, "xmax":300},
    'LeadingJet_pt':                {"name":'LeadingJet_pt',             "title": "Leading Jet Pt",                      "bin":100,  "xmin":0, "xmax":200},
    'SubleadingJet_pt':             {"name":'SubleadingJet_pt',          "title": "Subleading Jet Pt",                   "bin":100,  "xmin":0, "xmax":200},
    'LeadingJetParticles_PDG':      {"name":'LeadingJetParticles_PDG',   "title": "Leading cst PDG",                     "bin":100,  "xmin":0, "xmax":200},
    'SubleadingJetParticles_PDG':   {"name":'SubleadingJetParticles_PDG',"title": "Subleading cst PDG",                  "bin":200,  "xmin":0, "xmax":200},
}

Hi @sbenabde,

one minor problem I can see, from a quick look, is that the output directory of your final stage is different from the input directory of your plotting stage:

final stage:

outputDir = "DarkPhotons/FINAL_output"

vs. plotting stage:

inputDir       = 'DarkPhotons/histos/'

Can you also try listing one of the files coming out of the final stage with rootls -lt?

Best,
Juraj

Hi @jsmiesko,

The final stage scripts gives both _histos.root and .root files as output for each input file, so I tried putting only the histo.root files in a folder as inputDir for the plotting script, which is why the InputDir and OutputDir are different in the code version I pasted here. I have also tried running the script with the same final stage outputDir and plotting inputDir, but that did not solve the issue.

I have listed here both the histo.root and the .root outputs:

(.venv) [sbenabde@lxplus9108 FINAL_output]$ rootls -lt dark_photon_mZd500MeV_e_8.07e-6_Z-mass_jets_histo.root
TH1D               Feb 25 09:58 2026 LeadingJetParticles_PDG_raw;1    “”
TH1D               Feb 25 09:58 2026 LeadingJet_eta_raw;1             “”
TH1D               Feb 25 09:58 2026 LeadingJet_pt_raw;1              “”
TH1D               Feb 25 09:58 2026 Leading_jet_invMass_raw;1        “”
TH1D               Feb 25 09:58 2026 Leading_jets_invMass_raw;1       “”
TH1D               Feb 25 09:58 2026 RecoMuon1_pt_raw;1               “”
TH1D               Feb 25 09:58 2026 RecoMuon2_pt_raw;1               “”
TH1D               Feb 25 09:58 2026 RecoMuon3_pt_raw;1               “”
TH1D               Feb 25 09:58 2026 RecoMuon4_pt_raw;1               “”
TH1D               Feb 25 09:58 2026 RecoMuons_InvMass_raw;1          “”
TH1D               Feb 25 09:58 2026 SubleadingJetParticles_PDG_raw;1 “”
TH1D               Feb 25 09:58 2026 SubleadingJet_eta_raw;1          “”
TH1D               Feb 25 09:58 2026 SubleadingJet_pt_raw;1           “”
TH1D               Feb 25 09:58 2026 Subleading_jet_invMass_raw;1     “”
TParameter    Feb 25 09:58 2026 eventsProcessed;1                “”
TH1D               Feb 25 09:58 2026 n_RecoMuons_raw;1                “”
TParameter   Feb 25 09:58 2026 scaled;1                         “”
TParameter  Feb 25 09:58 2026 sumOfWeights;1                   “”
(.venv) [sbenabde@lxplus9108 FINAL_output]$ rootls -lt dark_photon_mZd500MeV_e_8.07e-6_Z-mass_jets.root
TTree            Feb 20 18:12 2026 events;1          “events”
n_FSGenMuon             “n_FSGenMuon/I”             1636
FSGenMuon_e             “FSGenMuon_e”               11970
FSGenMuon_p             “FSGenMuon_p”               11970
FSGenMuon_pt            “FSGenMuon_pt”              11971
FSGenMuon_px            “FSGenMuon_px”              11971
FSGenMuon_py            “FSGenMuon_py”              11971
FSGenMuon_pz            “FSGenMuon_pz”              11971
FSGenMuon_eta           “FSGenMuon_eta”             11972
FSGenMuon_theta         “FSGenMuon_theta”           11974
FSGenMuon_phi           “FSGenMuon_phi”             11972
FSGenMuon_charge        “FSGenMuon_charge”          11975
FSGen_Lxy               “FSGen_Lxy”                 11968
FSGen_Lxyz              “FSGen_Lxyz”                11969
MC_n                    “MC_n/I”                    1629
MC_PDG                  “MC_PDG”                    11965
MC_M1_idx               “MC_M1_idx”                 11968
MC_M1_part              “MC_M1_part_”               3199
MC_M1_part.PDG                   “PDG[MC_M1_part_]”              8083
MC_M1_part.generatorStatus       “generatorStatus[MC_M1_part_]”  8095
MC_M1_part.simulatorStatus       “simulatorStatus[MC_M1_part_]”  8095
MC_M1_part.charge                “charge[MC_M1_part_]”           8086
MC_M1_part.time                  “time[MC_M1_part_]”             8084
MC_M1_part.mass                  “mass[MC_M1_part_]”             14520
MC_M1_part.vertex.x              “x[MC_M1_part_]”                14524
MC_M1_part.vertex.y              “y[MC_M1_part_]”                14524
MC_M1_part.vertex.z              “z[MC_M1_part_]”                14524
MC_M1_part.endpoint.x            “x[MC_M1_part_]”                14526
MC_M1_part.endpoint.y            “y[MC_M1_part_]”                14526
MC_M1_part.endpoint.z            “z[MC_M1_part_]”                14526
MC_M1_part.momentum.x            “x[MC_M1_part_]”                14526
MC_M1_part.momentum.y            “y[MC_M1_part_]”                14526
MC_M1_part.momentum.z            “z[MC_M1_part_]”                14526
MC_M1_part.momentumAtEndpoint.x  “x[MC_M1_part_]”                14536
MC_M1_part.momentumAtEndpoint.y  “y[MC_M1_part_]”                14536
MC_M1_part.momentumAtEndpoint.z  “z[MC_M1_part_]”                14536
MC_M1_part.helicity              “helicity[MC_M1_part_]”         8088
MC_M1_part.parents_begin         “parents_begin[MC_M1_part_]”    8093
MC_M1_part.parents_end           “parents_end[MC_M1_part_]”      8091
MC_M1_part.daughters_begin       “daughters_begin[MC_M1_part_]”  8095
MC_M1_part.daughters_end         “daughters_end[MC_M1_part_]”    8093
MC_M1_pdg               “MC_M1_pdg”                 11968
n_RecoMuons             “n_RecoMuons/I”             1636
RecoMuon_pt             “RecoMuon_pt”               11586
RecoMuon_eta            “RecoMuon_eta”              11587
RecoMuon_p              “RecoMuon_p”                11585
RecoMuon_e              “RecoMuon_e”                11585
RecoMuon_px             “RecoMuon_px”               11586
RecoMuon_py             “RecoMuon_py”               11586
RecoMuon_pz             “RecoMuon_pz”               11586
RecoMuon_theta          “RecoMuon_theta”            11589
RecoMuon_phi            “RecoMuon_phi”              11587
RecoMuon_charge         “RecoMuon_charge”           11590
RecoMuons_InvMass       “RecoMuons_InvMass/F”       1642
RecoMuons_charge        “RecoMuons_charge/F”        1641
RecoMuon1_pt            “RecoMuon1_pt/F”            1637
RecoMuon2_pt            “RecoMuon2_pt/F”            1637
RecoMuon3_pt            “RecoMuon3_pt/F”            1637
RecoMuon4_pt            “RecoMuon4_pt/F”            1637
n_RecoJets              “n_RecoJets/I”              1635
RecoJet_e               “RecoJet_e”                 10412
RecoJet_p               “RecoJet_p”                 10412
RecoJet_pt              “RecoJet_pt”                10413
RecoJet_px              “RecoJet_px”                10413
RecoJet_py              “RecoJet_py”                10413
RecoJet_pz              “RecoJet_pz”                10413
RecoJet_eta             “RecoJet_eta”               10414
RecoJet_theta           “RecoJet_theta”             10416
RecoJet_phi             “RecoJet_phi”               10414
RecoJet_charge          “RecoJet_charge”            10417
Reco_qq_invMass         “Reco_qq_invMass/F”         1640
LeadingJet_pt           “LeadingJet_pt/F”           1638
LeadingJet_eta          “LeadingJet_eta/F”          1639
SubleadingJet_pt        “SubleadingJet_pt/F”        1641
SubleadingJet_eta       “SubleadingJet_eta/F”       1642
Leading_jets_invMass    “Leading_jets_invMass/F”    1645
Leading_jet_invMass     “Leading_jet_invMass/F”     1644
Subleading_jet_invMass  “Subleading_jet_invMass/F”  1647
Cluster INCLUSIVE ranges:

0: [0, 388]

The total number of clusters is 1
TParameter  Feb 20 18:12 2026 eventsProcessed;1 “”

Hi @sbenabde,

I think I found the cause of the problem. There is a bug in the output logic of the histograms, when the user does not do any scaling to the histograms they are not written out. This PR should fix it:

Can you test it?

Best,
Juraj

Hi @jsmiesko,

Many thanks for your help! I think my mistake was a little silly: the final stage script returns a .root file where the variable names are appended with ‘_raw;1’. Adding this suffix to the variable names in the plotting script fixed the bug. Also, once this issue was fixed, the histograms I got were indeed empty. Removing the scaling lines completely fixed that issue! Thanks :slight_smile:

Kind regards,
Sarah

Hi @sbenabde,

Nice :slight_smile:

The _raw histograms are backup in case someone wants to examine the state before scaling, and normally should not be used.
In your case (after the fix) the raw and normal histograms should give the same plots.

The scaleSig and scaleBkg are additional scaling factors, and setting them to 0 clears out the histograms:

Best,
Juraj