void combinedFit() { TH1D * hB = new TH1D("hB","histo B",100,0,100); TH1D * hSB = new TH1D("hSB","histo S+B",100, 0,100); TF1 * fB = new TF1("fB","expo",0,100); fB->SetParameters(1,-0.05); hB->FillRandom("fB"); TF1 * fS = new TF1("fS","gaus",0,100); fS->SetParameters(1,30,5); hSB->FillRandom("fB",2000); hSB->FillRandom("fS",1000); // perform now global fit TF1 * fSB = new TF1("fSB","expo + gaus(2)",0,100); ROOT::Math::WrappedMultiTF1 wfB(*fB,1); ROOT::Math::WrappedMultiTF1 wfSB(*fSB,1); ROOT::Fit::DataOptions opt; ROOT::Fit::DataRange rangeB; // set the data range rangeB.SetRange(10,90); ROOT::Fit::BinData dataB(opt,rangeB); ROOT::Fit::FillData(dataB, hB); ROOT::Fit::DataRange rangeSB; rangeSB.SetRange(10,50); ROOT::Fit::BinData dataSB(opt,rangeSB); ROOT::Fit::FillData(dataSB, hSB); ROOT::Fit::Chi2Function chi2_B(dataB, wfB); ROOT::Fit::Chi2Function chi2_SB(dataSB, wfSB); GlobalChi2 globalChi2(chi2_B, chi2_SB); ROOT::Fit::Fitter fitter; const int Npar = 6; double par0[Npar] = { 5,5,-0.1,100, 30,10}; // create before the parameter settings in order to fix or set range on them fitter.Config().SetParamsSettings(6,par0); // fix 5-th parameter fitter.Config().ParSettings(4).Fix(); // set limits on the third and 4-th parameter fitter.Config().ParSettings(2).SetLimits(-10,-1.E-4); fitter.Config().ParSettings(3).SetLimits(0,10000); fitter.Config().ParSettings(3).SetStepSize(5); fitter.Config().MinimizerOptions().SetPrintLevel(0); fitter.Config().SetMinimizer("Minuit2","Migrad"); // fit FCN function directly // (specify optionally data size and flag to indicate that is a chi2 fit) fitter.FitFCN(6,globalChi2,0,dataB.Size()+dataSB.Size(),true); ROOT::Fit::FitResult result = fitter.Result(); result.Print(std::cout); TCanvas * c1 = new TCanvas("Simfit","Simultaneous fit of two histograms", 10,10,700,700); c1->Divide(1,2); c1->cd(1); gStyle->SetOptFit(1111); fB->SetFitResult( result, iparB); fB->SetRange(rangeB().first, rangeB().second); fB->SetLineColor(kBlue); hB->GetListOfFunctions()->Add(fB); hB->Draw(); c1->cd(2); fSB->SetFitResult( result, iparSB); fSB->SetRange(rangeSB().first, rangeSB().second); fSB->SetLineColor(kRed); hSB->GetListOfFunctions()->Add(fSB); hSB->Draw(); }
int main() { std::random_device rd; std::mt19937 gen(rd()); auto rngC = [&](){ return random_value<uint8_t>(gen); }; auto rngD = [&](){ return random_value<double>(gen); }; const bool randomize = false; //######################################## auto vectorDoubleTest = [&](size_t s, bool randomize_) { std::ostringstream name; name << "Vector(double) size " << s; std::vector<double> data(s); if(randomize_) for( auto & d : data ) d = rngD(); test<binary>( name.str(), data ); }; vectorDoubleTest(1, randomize); // 8B vectorDoubleTest(16, randomize); // 128B vectorDoubleTest(1024, randomize); // 8KB vectorDoubleTest(1024*1024, randomize); // 8MB //######################################## auto vectorCharTest = [&](size_t s, bool randomize_) { std::ostringstream name; name << "Vector(uint8_t) size " << s; std::vector<uint8_t> data(s); if(randomize_) for( auto & d : data ) d = rngC(); test<binary>( name.str(), data ); }; vectorCharTest(1024*1024*64, randomize); //######################################## auto vectorPoDStructTest = [&](size_t s) { std::ostringstream name; name << "Vector(PoDStruct) size " << s; std::vector<PoDStructCereal> dataC(s); std::vector<PoDStructBoost> dataB(s); test<binary>( name.str(), dataC, dataB ); }; vectorPoDStructTest(1); vectorPoDStructTest(64); vectorPoDStructTest(1024); vectorPoDStructTest(1024*1024); vectorPoDStructTest(1024*1024*2); //######################################## auto vectorPoDChildTest = [&](size_t s) { std::ostringstream name; name << "Vector(PoDChild) size " << s; std::vector<PoDChildCereal> dataC(s); std::vector<PoDChildBoost> dataB(s); test<binary>( name.str(), dataC, dataB ); }; vectorPoDChildTest(1024); vectorPoDChildTest(1024*32); //######################################## auto stringTest = [&](size_t s) { std::ostringstream name; name << "String size " << s; std::string data = random_basic_string<char>(gen, s); std::cout << "data.size " << data.size() << std::endl; test<binary>( name.str(), data ); }; stringTest(200000); stringTest(2000000); stringTest(20000000); //######################################## auto vectorStringTest = [&](size_t s) { std::ostringstream name; name << "Vector(String) size " << s; std::vector<std::string> data(s); for(size_t i=0; i<data.size(); ++i) data[i] = random_basic_string<char>(gen); test<binary>( name.str(), data ); }; vectorStringTest(512); vectorStringTest(1024); vectorStringTest(1024*64); vectorStringTest(1024*128); //######################################## auto mapPoDStructTest = [&](size_t s) { std::ostringstream name; name << "Map(PoDStruct) size " <<s; std::map<std::string, PoDStructCereal> mC; std::map<std::string, PoDStructBoost> mB; for(size_t i=0; i<s; ++i) { mC[std::to_string( i )] = PoDStructCereal(); mB[std::to_string( i )] = PoDStructBoost(); } test<binary>(name.str(), mC, mB); }; mapPoDStructTest(1024); mapPoDStructTest(1024*64); return 0; }