File indexing completed on 2024-04-06 11:57:17
0001 #include "Alignment/OfflineValidation/interface/FitWithRooFit.h"
0002
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004
0005
0006 std::unique_ptr<RooDataHist> FitWithRooFit::importTH1(TH1* histo, double xMin, double xMax) {
0007 if ((xMin == xMax) && xMin == 0) {
0008 xMin = histo->GetXaxis()->GetXmin();
0009 xMax = histo->GetXaxis()->GetXmax();
0010 }
0011
0012 RooRealVar x("InvMass", "di-muon mass M(#mu^{+}#mu^{-}) [GeV]", xMin, xMax);
0013
0014 return std::make_unique<RooDataHist>("dh", "dh", x, RooFit::Import(*histo));
0015 }
0016
0017
0018 void FitWithRooFit::fit(
0019 TH1* histo, const TString signalType, const TString backgroundType, double xMin, double xMax, bool sumW2Error) {
0020 reinitializeParameters();
0021
0022 std::unique_ptr<RooDataHist> dh = importTH1(histo, xMin, xMax);
0023 RooRealVar x(*static_cast<RooRealVar*>(dh->get()->find("InvMass")));
0024
0025
0026 RooPlot* frame = x.frame(RooFit::Title("di-muon mass M(#mu^{+}#mu^{-}) [GeV]"));
0027 frame->SetName(TString(histo->GetName()) + "_frame");
0028 dh->plotOn(frame);
0029
0030
0031 std::unique_ptr<RooAbsPdf> model = buildModel(&x, signalType, backgroundType);
0032
0033 std::unique_ptr<RooAbsReal> chi2{model->createChi2(*dh, RooFit::DataError(RooAbsData::SumW2))};
0034
0035
0036
0037
0038 if (!useChi2_) {
0039
0040 model->fitTo(*dh, RooFit::SumW2Error(sumW2Error), RooFit::PrintLevel(-1));
0041 }
0042
0043 else {
0044 edm::LogWarning("FitWithRooFit") << "FITTING WITH CHI^2";
0045 RooMinimizer m(*chi2);
0046 m.migrad();
0047 m.hesse();
0048
0049 }
0050
0051 model->plotOn(frame, RooFit::LineColor(kRed));
0052
0053
0054
0055
0056 model->paramOn(frame,
0057 RooFit::Label("fit result"),
0058 RooFit::Layout(0.65, 0.90, 0.90),
0059 RooFit::Format("NEU", RooFit::AutoPrecision(2)));
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 RooPlot* frame2 = x.frame(RooFit::Title("di-muon mass M(#mu^{+}#mu^{-}) [GeV]"));
0074 dh->plotOn(frame2, RooFit::DataError(RooAbsData::SumW2));
0075 model->plotOn(frame2, RooFit::LineColor(kRed));
0076
0077
0078
0079 model->paramOn(frame2,
0080 RooFit::Label("fit result"),
0081 RooFit::Layout(0.65, 0.90, 0.90),
0082 RooFit::Format("NEU", RooFit::AutoPrecision(2)));
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 frame2->Draw();
0101 }
0102
0103
0104 void FitWithRooFit::initMean(double value, double min, double max, const TString& name, const TString& title) {
0105 mean_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0106 initVal_mean = value;
0107 }
0108
0109 void FitWithRooFit::initMean2(double value, double min, double max, const TString& name, const TString& title) {
0110 mean2_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0111 initVal_mean2 = value;
0112 }
0113
0114 void FitWithRooFit::initMean3(double value, double min, double max, const TString& name, const TString& title) {
0115 mean3_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0116 initVal_mean3 = value;
0117 }
0118
0119 void FitWithRooFit::initSigma(double value, double min, double max, const TString& name, const TString& title) {
0120 sigma_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0121 initVal_sigma = value;
0122 }
0123
0124 void FitWithRooFit::initSigma2(double value, double min, double max, const TString& name, const TString& title) {
0125 sigma2_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0126 initVal_sigma2 = value;
0127 }
0128
0129 void FitWithRooFit::initSigma3(double value, double min, double max, const TString& name, const TString& title) {
0130 sigma3_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0131 initVal_sigma3 = value;
0132 }
0133
0134 void FitWithRooFit::initGamma(double value, double min, double max, const TString& name, const TString& title) {
0135 gamma_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0136 initVal_gamma = value;
0137 }
0138
0139 void FitWithRooFit::initGaussFrac(double value, double min, double max, const TString& name, const TString& title) {
0140 gaussFrac_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0141 initVal_gaussFrac = value;
0142 }
0143
0144 void FitWithRooFit::initGaussFrac2(double value, double min, double max, const TString& name, const TString& title) {
0145 gaussFrac2_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0146 initVal_gaussFrac2 = value;
0147 }
0148
0149 void FitWithRooFit::initExpCoeffA0(double value, double min, double max, const TString& name, const TString& title) {
0150 expCoeffa0_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0151 initVal_expCoeffa0 = value;
0152 }
0153
0154 void FitWithRooFit::initExpCoeffA1(double value, double min, double max, const TString& name, const TString& title) {
0155 expCoeffa1_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0156 initVal_expCoeffa1 = value;
0157 }
0158
0159 void FitWithRooFit::initExpCoeffA2(double value, double min, double max, const TString& name, const TString& title) {
0160 expCoeffa2_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0161 initVal_expCoeffa2 = value;
0162 }
0163
0164 void FitWithRooFit::initFsig(double value, double min, double max, const TString& name, const TString& title) {
0165 fsig_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0166 initVal_fsig = value;
0167 }
0168
0169 void FitWithRooFit::initA0(double value, double min, double max, const TString& name, const TString& title) {
0170 a0_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0171 initVal_a0 = value;
0172 }
0173
0174 void FitWithRooFit::initA1(double value, double min, double max, const TString& name, const TString& title) {
0175 a1_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0176 initVal_a1 = value;
0177 }
0178
0179 void FitWithRooFit::initA2(double value, double min, double max, const TString& name, const TString& title) {
0180 a2_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0181 initVal_a2 = value;
0182 }
0183
0184 void FitWithRooFit::initA3(double value, double min, double max, const TString& name, const TString& title) {
0185 a3_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0186 initVal_a3 = value;
0187 }
0188
0189 void FitWithRooFit::initA4(double value, double min, double max, const TString& name, const TString& title) {
0190 a4_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0191 initVal_a4 = value;
0192 }
0193
0194 void FitWithRooFit::initA5(double value, double min, double max, const TString& name, const TString& title) {
0195 a5_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0196 initVal_a5 = value;
0197 }
0198
0199 void FitWithRooFit::initA6(double value, double min, double max, const TString& name, const TString& title) {
0200 a6_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0201 initVal_a6 = value;
0202 }
0203
0204 void FitWithRooFit::initAlpha(double value, double min, double max, const TString& name, const TString& title) {
0205 alpha_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0206 initVal_alpha = value;
0207 }
0208
0209 void FitWithRooFit::initN(double value, double min, double max, const TString& name, const TString& title) {
0210 n_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0211 initVal_n = value;
0212 }
0213
0214 void FitWithRooFit::initFGCB(double value, double min, double max, const TString& name, const TString& title) {
0215 fGCB_ = std::make_unique<RooRealVar>(name, title, value, min, max);
0216 initVal_fGCB = value;
0217 }
0218
0219 void FitWithRooFit::reinitializeParameters() {
0220 auto initParam = [](std::unique_ptr<RooRealVar>& var, double val) {
0221 if (var)
0222 var->setVal(val);
0223 };
0224
0225 initParam(mean_, initVal_mean);
0226 initParam(mean2_, initVal_mean2);
0227 initParam(mean3_, initVal_mean3);
0228 initParam(sigma_, initVal_sigma);
0229 initParam(sigma2_, initVal_sigma2);
0230 initParam(sigma3_, initVal_sigma3);
0231 initParam(gamma_, initVal_gamma);
0232 initParam(gaussFrac_, initVal_gaussFrac);
0233 initParam(gaussFrac2_, initVal_gaussFrac2);
0234 initParam(expCoeffa0_, initVal_expCoeffa0);
0235 initParam(expCoeffa1_, initVal_expCoeffa1);
0236 initParam(expCoeffa2_, initVal_expCoeffa2);
0237 initParam(fsig_, initVal_fsig);
0238 initParam(a0_, initVal_a0);
0239 initParam(a1_, initVal_a1);
0240 initParam(a2_, initVal_a2);
0241 initParam(a3_, initVal_a3);
0242 initParam(a4_, initVal_a4);
0243 initParam(a5_, initVal_a5);
0244 initParam(a6_, initVal_a6);
0245 initParam(alpha_, initVal_alpha);
0246 initParam(n_, initVal_n);
0247 initParam(fGCB_, initVal_fGCB);
0248 }
0249
0250
0251 std::unique_ptr<RooAbsPdf> FitWithRooFit::buildSignalModel(RooRealVar* x, const TString& signalType) {
0252 if (signalType == "gaussian") {
0253
0254 if ((mean_ == nullptr) || (sigma_ == nullptr)) {
0255 edm::LogError("FitWithRooFit")
0256 << "Error: one or more parameters are not initialized. Please be sure to initialize mean and sigma";
0257 exit(1);
0258 }
0259 return std::make_unique<RooGaussian>("gauss", "gauss", *x, *mean_, *sigma_);
0260 } else if (signalType == "doubleGaussian") {
0261
0262 if ((mean_ == nullptr) || (sigma_ == nullptr) || (sigma2_ == nullptr)) {
0263 edm::LogError("FitWithRooFit")
0264 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and sigma2";
0265 exit(1);
0266 }
0267 RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_);
0268 RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean_, *sigma2_);
0269 RooArgList components{*gaussModel, *gaussModel2};
0270 auto out = std::make_unique<RooAddModel>("doubleGaussian", "double gaussian", components, *gaussFrac_);
0271 out->addOwnedComponents(components);
0272 return out;
0273 } else if (signalType == "tripleGaussian") {
0274
0275 if ((mean_ == nullptr) || (mean2_ == nullptr) || (mean3_ == nullptr) || (sigma_ == nullptr) ||
0276 (sigma2_ == nullptr) || (sigma3_ == nullptr)) {
0277 edm::LogError("FitWithRooFit")
0278 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
0279 "mean3, sigma, sigma2, sigma3";
0280 exit(1);
0281 }
0282 RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_);
0283 RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean2_, *sigma2_);
0284 RooGaussModel* gaussModel3 = new RooGaussModel("gaussModel3", "gaussModel3", *x, *mean3_, *sigma3_);
0285 RooArgList components{*gaussModel, *gaussModel2, *gaussModel3};
0286 auto out = std::make_unique<RooAddModel>(
0287 "tripleGaussian", "triple gaussian", components, RooArgList{*gaussFrac_, *gaussFrac2_});
0288 out->addOwnedComponents(components);
0289 return out;
0290 } else if (signalType == "breitWigner") {
0291
0292 if ((mean_ == nullptr) || (gamma_ == nullptr)) {
0293 edm::LogError("FitWithRooFit")
0294 << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma";
0295 exit(1);
0296 }
0297 return std::make_unique<RooBreitWigner>("breiWign", "breitWign", *x, *mean_, *gamma_);
0298 } else if (signalType == "relBreitWigner") {
0299
0300 if ((mean_ == nullptr) || (gamma_ == nullptr)) {
0301 edm::LogError("FitWithRooFit")
0302 << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma";
0303 exit(1);
0304 }
0305 return std::make_unique<RooGenericPdf>("Relativistic Breit-Wigner",
0306 "RBW",
0307 "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))",
0308 RooArgList{*x, *mean_, *gamma_});
0309 } else if (signalType == "voigtian") {
0310
0311 if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr)) {
0312 edm::LogError("FitWithRooFit")
0313 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and gamma";
0314 exit(1);
0315 }
0316 return std::make_unique<RooVoigtian>("voigt", "voigt", *x, *mean_, *gamma_, *sigma_);
0317 } else if (signalType == "crystalBall") {
0318
0319 if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr)) {
0320 edm::LogError("FitWithRooFit")
0321 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, "
0322 "alpha and n";
0323 exit(1);
0324 }
0325 return std::make_unique<RooCBShape>("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_);
0326 } else if (signalType == "breitWignerTimesCB") {
0327
0328 if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) ||
0329 (alpha_ == nullptr) || (n_ == nullptr)) {
0330 edm::LogError("FitWithRooFit")
0331 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
0332 "sigma, gamma, alpha and n";
0333 exit(1);
0334 }
0335 RooAbsPdf* bw = new RooBreitWigner("breiWigner", "breitWigner", *x, *mean_, *gamma_);
0336 RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_);
0337 auto out = std::make_unique<RooFFTConvPdf>("breitWignerTimesCB", "breitWignerTimesCB", *x, *bw, *cb);
0338 out->addOwnedComponents({*bw, *cb});
0339 return out;
0340 } else if (signalType == "relBreitWignerTimesCB") {
0341
0342 if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) ||
0343 (alpha_ == nullptr) || (n_ == nullptr)) {
0344 edm::LogError("FitWithRooFit")
0345 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
0346 "sigma, gamma, alpha and n";
0347 exit(1);
0348 }
0349 RooGenericPdf* bw = new RooGenericPdf("Relativistic Breit-Wigner",
0350 "RBW",
0351 "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))",
0352 {*x, *mean_, *gamma_});
0353 RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_);
0354 auto out = std::make_unique<RooFFTConvPdf>("relBreitWignerTimesCB", "relBreitWignerTimesCB", *x, *bw, *cb);
0355 out->addOwnedComponents({*bw, *cb});
0356 return out;
0357 } else if (signalType == "gaussianPlusCrystalBall") {
0358
0359 if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) ||
0360 (fGCB_ == nullptr)) {
0361 edm::LogError("FitWithRooFit")
0362 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, "
0363 "sigma2, alpha, n and fGCB";
0364 exit(1);
0365 }
0366 RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_);
0367 RooAbsPdf* tempGaussian = new RooGaussian("gauss", "gauss", *x, *mean_, *sigma2_);
0368 RooArgList components{*tempCB, *tempGaussian};
0369
0370 auto out = std::make_unique<RooAddPdf>("gaussianPlusCrystalBall", "gaussianPlusCrystalBall", components, *fGCB_);
0371 out->addOwnedComponents(components);
0372 return out;
0373 } else if (signalType == "voigtianPlusCrystalBall") {
0374
0375 if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) ||
0376 (sigma2_ == nullptr) || (fGCB_ == nullptr)) {
0377 edm::LogError("FitWithRooFit")
0378 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, "
0379 "sigma, sigma2, alpha, n and fGCB";
0380 exit(1);
0381 }
0382 RooAbsPdf* tempVoigt = new RooVoigtian("voigt", "voigt", *x, *mean_, *gamma_, *sigma_);
0383 RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_);
0384 RooArgList components{*tempVoigt, *tempCB};
0385
0386 auto out = std::make_unique<RooAddPdf>("voigtianPlusCrystalBall", "voigtianPlusCrystalBall", components, *fGCB_);
0387 out->addOwnedComponents(components);
0388 return out;
0389 } else if (signalType == "breitWignerPlusCrystalBall") {
0390
0391 if ((mean_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) ||
0392 (fGCB_ == nullptr)) {
0393 edm::LogError("FitWithRooFit")
0394 << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, "
0395 "sigma, alpha, n and fGCB";
0396 exit(1);
0397 }
0398 RooAbsPdf* tempBW = new RooBreitWigner("breitWign", "breitWign", *x, *mean_, *gamma_);
0399 RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_);
0400 RooArgList components{*tempCB, *tempBW};
0401
0402 auto out =
0403 std::make_unique<RooAddPdf>("breitWignerPlusCrystalBall", "breitWignerPlusCrystalBall", components, *fGCB_);
0404 out->addOwnedComponents(components);
0405 return out;
0406 }
0407
0408 else if (signalType != "") {
0409 edm::LogError("FitWithRooFit") << "Unknown signal function: " << signalType << ". Signal will not be in the model";
0410 }
0411 return nullptr;
0412 }
0413
0414
0415 std::unique_ptr<RooAbsPdf> FitWithRooFit::buildBackgroundModel(RooRealVar* x, const TString& backgroundType) {
0416 if (backgroundType == "exponential") {
0417
0418 if ((expCoeffa1_ == nullptr) || (fsig_ == nullptr)) {
0419 edm::LogError("FitWithRooFit")
0420 << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeffa1 and fsig";
0421 exit(1);
0422 }
0423 return std::make_unique<RooExponential>("exponential", "exponential", *x, *expCoeffa1_);
0424 }
0425
0426 if (backgroundType == "exponentialpol") {
0427
0428 if ((expCoeffa0_ == nullptr) || (expCoeffa1_ == nullptr) || (expCoeffa2_ == nullptr) || (fsig_ == nullptr)) {
0429 edm::LogError("FitWithRooFit")
0430 << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeff and fsig";
0431 exit(1);
0432 }
0433 return std::make_unique<RooGenericPdf>("exponential",
0434 "exponential",
0435 "TMath::Exp(@1+@2*@0+@3*@0*@0)",
0436 RooArgList{*x, *expCoeffa0_, *expCoeffa1_, *expCoeffa2_});
0437 }
0438
0439 else if (backgroundType == "chebychev0") {
0440
0441 if (a0_ == nullptr) {
0442 edm::LogError("FitWithRooFit")
0443 << "Error: one or more parameters are not initialized. Please be sure to initialize a0";
0444 exit(1);
0445 }
0446 return std::make_unique<RooChebychev>("chebychev0", "chebychev0", *x, *a0_);
0447 } else if (backgroundType == "chebychev1") {
0448
0449 if ((a0_ == nullptr) || (a1_ == nullptr)) {
0450 edm::LogError("FitWithRooFit")
0451 << "Error: one or more parameters are not initialized. Please be sure to initialize a0 and a1";
0452 exit(1);
0453 }
0454 return std::make_unique<RooChebychev>("chebychev1", "chebychev1", *x, RooArgList{*a0_, *a1_});
0455 } else if (backgroundType == "chebychev3") {
0456
0457 if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr)) {
0458 edm::LogError("FitWithRooFit")
0459 << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2 and a3";
0460 exit(1);
0461 }
0462 return std::make_unique<RooChebychev>("3rdOrderPol", "3rdOrderPol", *x, RooArgList{*a0_, *a1_, *a2_, *a3_});
0463 }
0464
0465 else if (backgroundType == "chebychev6") {
0466
0467 if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr) || (a4_ == nullptr) ||
0468 (a5_ == nullptr) || (a6_ == nullptr)) {
0469 edm::LogError("FitWithRooFit")
0470 << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2, a3, "
0471 "a4, a5 and a6";
0472 exit(1);
0473 }
0474 return std::make_unique<RooChebychev>(
0475 "6thOrderPol", "6thOrderPol", *x, RooArgList{*a0_, *a1_, *a2_, *a3_, *a4_, *a5_, *a6_});
0476 }
0477 return nullptr;
0478 }
0479
0480
0481 std::unique_ptr<RooAbsPdf> FitWithRooFit::buildModel(RooRealVar* x,
0482 const TString& signalType,
0483 const TString& backgroundType) {
0484 std::unique_ptr<RooAbsPdf> model;
0485
0486 std::unique_ptr<RooAbsPdf> signal = buildSignalModel(x, signalType);
0487 std::unique_ptr<RooAbsPdf> background = buildBackgroundModel(x, backgroundType);
0488
0489 if ((signal != nullptr) && (background != nullptr)) {
0490
0491 edm::LogPrint("FitWithRooFit") << "Building model with signal and backgound";
0492 RooArgList components{*signal.release(), *background.release()};
0493 model = std::make_unique<RooAddPdf>("model", "model", components, *fsig_);
0494 model->addOwnedComponents(components);
0495 } else if (signal != nullptr) {
0496 edm::LogPrint("FitWithRooFit") << "Building model with signal";
0497 model = std::move(signal);
0498 } else if (background != nullptr) {
0499 edm::LogPrint("FitWithRooFit") << "Building model with backgound";
0500 model = std::move(background);
0501 } else {
0502 edm::LogWarning("FitWithRooFit") << "Nothing to fit";
0503 exit(0);
0504 }
0505 return model;
0506 }