File indexing completed on 2026-05-23 08:12:15
0001 #include "analysisHelper.h"
0002 #include "RooUnfold.h"
0003 #include "RooUnfoldResponse.h"
0004 #include "RooUnfoldBayes.h"
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 void wEEC_doUnfolding(const char* respFile,
0032 const char* outFileName,
0033 int nIterWEEC = 4,
0034 Mode mode = Mode::kFull,
0035 const char* measFile = nullptr,
0036 int minCounts = 0)
0037 {
0038 const bool isData = (mode == Mode::kData);
0039 const bool isClosure = !isData;
0040 const bool doTrim = false;
0041 if (isData && !measFile) {
0042 std::cerr << "kData mode requires measFile\n"; return;
0043 }
0044
0045 TFile* fResp = TFile::Open(respFile, "READ");
0046 if (!fResp || fResp->IsZombie()) {
0047 std::cerr << "Cannot open " << respFile << "\n"; return;
0048 }
0049
0050 TFile* fMeas = nullptr;
0051 if (isData) {
0052 fMeas = TFile::Open(measFile, "READ");
0053 if (!fMeas || fMeas->IsZombie()) {
0054 std::cerr << "Cannot open " << measFile << "\n"; return;
0055 }
0056 }
0057 TFile* fMeasSrc = fMeas ? fMeas : fResp;
0058
0059 TFile* fOut = new TFile(outFileName, "RECREATE");
0060
0061 auto meas3DName = [&](int k) -> std::string {
0062 return isData
0063 ? std::format("hWEEC3D_data_{}", k)
0064 : std::format("hWEEC3D_meas_{}", k);
0065 };
0066
0067
0068 {
0069 RooUnfoldResponse* respJetPt =
0070 (RooUnfoldResponse*)fResp->Get("response_jet_pT");
0071 if (!respJetPt) {
0072 std::cerr << "Warning: cannot find response_jet_pT — skipping jet pT unfolding\n";
0073 } else {
0074 TH1D* hJetPt_input = nullptr;
0075 if (mode == Mode::kFull) {
0076 hJetPt_input = (TH1D*)fResp->Get("hJetPt_reco");
0077 if (hJetPt_input) {
0078 hJetPt_input = (TH1D*)hJetPt_input->Clone("hJetPt_meas");
0079 hJetPt_input->SetDirectory(0);
0080 }
0081 } else {
0082 hJetPt_input = (TH1D*)fResp->Get("hJetPt_meas");
0083 if (hJetPt_input) {
0084 hJetPt_input = (TH1D*)hJetPt_input->Clone();
0085 hJetPt_input->SetDirectory(0);
0086 }
0087 }
0088
0089 if (hJetPt_input) {
0090 RooUnfoldBayes unfoldJet(respJetPt, hJetPt_input, 4);
0091 unfoldJet.HandleFakes(true);
0092 TH1D* hJetPt_unfolded = (TH1D*)unfoldJet.Hunfold();
0093 hJetPt_unfolded->SetDirectory(0);
0094 hJetPt_unfolded->SetName("hJetPt_unfolded");
0095
0096 fOut->cd();
0097 hJetPt_input->Write("hJetPt_meas");
0098 hJetPt_unfolded->Write();
0099
0100 if (isClosure) {
0101 TH1D* hJetPt_truth = (TH1D*)fResp->Get("hJetPt_truth");
0102 if (hJetPt_truth) {
0103 hJetPt_truth->SetDirectory(0);
0104 hJetPt_truth->Write();
0105 }
0106 }
0107
0108 delete hJetPt_input;
0109 delete hJetPt_unfolded;
0110 }
0111 }
0112 }
0113
0114
0115 for (int k = 0; k < nDphi; ++k)
0116 {
0117 TH1D* hMeas = (TH1D*)fMeasSrc->Get(meas3DName(k).c_str());
0118 if (!hMeas || hMeas->Integral() == 0) continue;
0119
0120 TH1D* hMeasClone = (TH1D*)hMeas->Clone(
0121 std::format("hWEEC3D_meas_{}", k).c_str());
0122 hMeasClone->SetDirectory(0);
0123
0124 RooUnfoldResponse* resp =
0125 (RooUnfoldResponse*)fResp->Get(
0126 std::format("response_wEEC3D_{}", k).c_str());
0127 if (!resp) { delete hMeasClone; continue; }
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 TH2D* hCounts = (TH2D*)fResp->Get(
0139 std::format("hWEEC3D_counts_{}", k).c_str());
0140
0141 RooUnfoldResponse* respTrimmed = nullptr;
0142
0143 TH2D* hResp2D = (TH2D*)resp->Hresponse()->Clone();
0144 if (doTrim && hCounts) {
0145 for (int rBin = 1; rBin <= hResp2D->GetNbinsX(); ++rBin)
0146 for (int tBin = 1; tBin <= hResp2D->GetNbinsY(); ++tBin) {
0147 double rawCount = hCounts->GetBinContent(rBin, tBin);
0148 if (rawCount < minCounts)
0149 hResp2D->SetBinContent(rBin, tBin, 0.0);
0150 }
0151 respTrimmed = new RooUnfoldResponse((TH1D*)resp->Hmeasured()->Clone(), (TH1D*)resp->Htruth()->Clone(), hResp2D);
0152 }
0153
0154
0155 RooUnfoldResponse *respToUse = (doTrim && respTrimmed != nullptr) ? respTrimmed : resp;
0156
0157
0158 std::cout << "Unfolding ΔΦ bin " << k << std::endl;
0159
0160
0161
0162
0163 RooUnfoldBayes unfold(respToUse, hMeasClone, nIterWEEC);
0164 unfold.HandleFakes(true);
0165 TH1D* hUnf = (TH1D*)unfold.Hunfold(RooUnfold::ErrorTreatment::kCovariance);
0166 hUnf->SetDirectory(0);
0167 hUnf->SetName(std::format("hWEEC3D_unfolded_{}", k).c_str());
0168 TMatrixD covM = (TMatrixD)unfold.Eunfold(RooUnfold::ErrorTreatment::kCovariance);
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 TMatrixD M = unfold.UnfoldingMatrix();
0183 int nT = hUnf->GetNbinsX();
0184 int nR = hMeasClone->GetNbinsX();
0185
0186
0187 TMatrixD Vmeas(nR, nR);
0188 for (int i = 0; i < nR; ++i)
0189 Vmeas(i, i) = std::pow(hMeasClone->GetBinError(i + 1), 2);
0190
0191
0192 TMatrixD Mtrim(nT, nR);
0193 for (int i = 0; i < nT; ++i)
0194 for (int j = 0; j < nR; ++j)
0195 Mtrim(i, j) = M(i, j);
0196
0197 TMatrixD MT(TMatrixD::kTransposed, Mtrim);
0198 TMatrixD cov = Mtrim * Vmeas * MT;
0199
0200
0201
0202
0203
0204
0205 hUnf->Sumw2();
0206 for (int i = 0; i < nT; ++i)
0207
0208 hUnf->SetBinError(i + 1, std::sqrt(std::max(covM(i, i), 0.0)));
0209
0210
0211 if (k == 0) {
0212 for (int i = 0; i < nR; ++i) {
0213 double v = hMeasClone->GetBinContent(i+1);
0214 double e = hMeasClone->GetBinError(i+1);
0215 if (v > 0 || e > 0) {
0216 std::cout << std::format(
0217 " First non-zero meas bin {}: content={:.3e} error={:.3e} rel={:.3f}\n",
0218 i, v, e, (v > 0 ? e/v : 0.0));
0219 break;
0220 }
0221 }
0222 for (int i = 0; i < nT; ++i) {
0223 if (cov(i,i) > 0) {
0224 std::cout << std::format(
0225 " First non-zero cov diag bin {}: cov={:.3e} hUnfErr^2={:.3e}\n",
0226 i, cov(i,i), std::pow(hUnf->GetBinError(i+1), 2));
0227 break;
0228 }
0229 }
0230 }
0231
0232 fOut->cd();
0233 hMeasClone->Write();
0234 hUnf->Write();
0235 covM.Write(std::format("covDirectWEEC3D_{}",k).c_str());
0236 cov.Write(std::format("covWEEC3D_{}", k).c_str());
0237 if (doTrim && respTrimmed)
0238 respTrimmed->Write(std::format("response_wEEC3D_trimmed_{}", k).c_str());
0239
0240 delete hMeasClone;
0241 delete hUnf;
0242 if (doTrim && respTrimmed) delete respTrimmed;
0243 }
0244
0245 fResp->Close(); delete fResp;
0246 if (fMeas) { fMeas->Close(); delete fMeas; }
0247 fOut->Close();
0248 std::cout << "Written: " << outFileName << "\n";
0249 }