void ProcessSignal() { signal.Scale(3); signal.WriteHSpiceSignalInclude("../ASDBLR/hspice.inc","isource","n1a","0"); system("hspice ../ASDBLR/ASDSigs.hsp >hspice.out"); Signals::Signal Ternary(0.5); std::vector<std::string> TernaryVar; TernaryVar.push_back("ternary"); TernaryVar.push_back(""); TernaryVar.push_back(""); Ternary.ReadSignalFromHSpicelis("hspice.out",TernaryVar); Ternary.Shift(-Ternary.GetSignalBin(0)); Signals::Discriminate disc(0.5,0.4); Signals::Rebin rebin(25); Signals::Discriminate lowdisc(0.5,0.1); Signals::Rebin lowrebin(3.125); Ternary>>disc>>rebin; Ternary>>lowdisc>>lowrebin; std::cout<<"FirstBins:"<<rebin.FirstBinBlock()<<std::endl; std::cout<<"LowFirstBins:"<<lowrebin.FirstBinBlock()<<std::endl; std::cout<<"Ternary"<<Ternary.IntegralBelow(0)<<std::endl; std::cout<<lowdist<<std::endl; lowdist->Fill(lowrebin.FirstBinBlock()); std::cout<<highdist<<std::endl; highdist->Fill(rebin.FirstBinBlock()); std::cout<<"FILL//"<<std::endl; }
/** * Reacts to the user selecting the BinMD algorithm */ void StandardView::onRebin() { if (QAction *action = dynamic_cast<QAction *>(sender())) { // split always returns a list of at least one element QString algName = getAlgNameFromMenuLabel(action->text()); emit rebin(algName.toStdString()); } }
unsigned int ProcessSignal(Signals::Signal& signal,std::string signalid) { signal.Graph()->Draw("AL"); canvas->Update(); canvas->Print(("debs/"+signalid+"sig.pdf").c_str()); signal.WriteHSpiceSignalInclude("../ASDBLR/hspice.inc","isource","n1a","0"); system("hspice ../ASDBLR/ASDSigs.hsp >hspice.out"); Signals::Signal Ternary(0.5); std::vector<std::string> TernaryVar; TernaryVar.push_back("ternary"); TernaryVar.push_back(""); TernaryVar.push_back(""); Ternary.ReadSignalFromHSpicelis("hspice.out",TernaryVar); Ternary.Shift(-Ternary.GetSignalBin(0)); Ternary.Graph()->Draw("AL"); canvas->Update(); canvas->Print(("debs/"+signalid+"ter.pdf").c_str()); Signals::Discriminate disc(0.5,0.4); Signals::Rebin rebin(25); Signals::Discriminate lowdisc(0.5,0.1); Signals::Rebin lowrebin(3.125); Ternary>>disc>>rebin; Ternary>>lowdisc>>lowrebin; leadingb=disc.LeadingBin()*disc.GetSignalBinTime(); trailingb=disc.TrailingBin()*disc.GetSignalBinTime(); lastbinblock=disc.LastBinBlock()*disc.GetSignalBinTime(); return disc.FirstBinBlock()*disc.GetSignalBinTime(); }
TH2F* smoothtemplates(TH2F* inputdata, int sampleIndex){ if(sampleIndex<3){ rebin(inputdata,sampleIndex); } else if(sampleIndex>2){ rebin_lowstatistics(inputdata,sampleIndex); } return inputdata; }
void vegas(double regn[], int ndim, double (*fxn)(double [], double), int init, unsigned long ncall, int itmx, int nprn, double *tgral, double *sd, double *chi2a) { double ran2(long *idum); void rebin(double rc, int nd, double r[], double xin[], double xi[]); static int i,it,j,k,mds,nd,ndo,ng,npg,ia[MXDIM+1],kg[MXDIM+1]; static double calls,dv2g,dxg,f,f2,f2b,fb,rc,ti,tsi,wgt,xjac,xn,xnd,xo; static double d[NDMX+1][MXDIM+1],di[NDMX+1][MXDIM+1],dt[MXDIM+1], dx[MXDIM+1], r[NDMX+1],x[MXDIM+1],xi[MXDIM+1][NDMX+1],xin[NDMX+1]; static double schi,si,swgt; if (init <= 0) { mds=ndo=1; for (j=1;j<=ndim;j++) xi[j][1]=1.0; } if (init <= 1) si=swgt=schi=0.0; if (init <= 2) { nd=NDMX; ng=1; if (mds) { ng=(int)pow(ncall/2.0+0.25,1.0/ndim); mds=1; if ((2*ng-NDMX) >= 0) { mds = -1; npg=ng/NDMX+1; nd=ng/npg; ng=npg*nd; } } for (k=1,i=1;i<=ndim;i++) k *= ng; npg=IMAX(ncall/k,2); calls=(double)npg * (double)k; dxg=1.0/ng; for (dv2g=1,i=1;i<=ndim;i++) dv2g *= dxg; dv2g=SQR(calls*dv2g)/npg/npg/(npg-1.0); xnd=nd; dxg *= xnd; xjac=1.0/calls; for (j=1;j<=ndim;j++) { dx[j]=regn[j+ndim]-regn[j]; xjac *= dx[j]; } if (nd != ndo) { for (i=1;i<=IMAX(nd,ndo);i++) r[i]=1.0; for (j=1;j<=ndim;j++) rebin(ndo/xnd,nd,r,xin,xi[j]); ndo=nd; } if (nprn >= 0) { // printf("%s: ndim= %3d ncall= %8.0f\n", // " Input parameters for vegas",ndim,calls); // printf("%28s it=%5d itmx=%5d\n"," ",it,itmx); // printf("%28s nprn=%3d ALPH=%5.2f\n"," ",nprn,ALPH); // printf("%28s mds=%3d nd=%4d\n"," ",mds,nd); // for (j=1;j<=ndim;j++) { // printf("%30s xl[%2d]= %11.4g xu[%2d]= %11.4g\n", // " ",j,regn[j],j,regn[j+ndim]); // } } } for (it=1;it<=itmx;it++) { ti=tsi=0.0; for (j=1;j<=ndim;j++) { kg[j]=1; for (i=1;i<=nd;i++) d[i][j]=di[i][j]=0.0; } for (;;) { fb=f2b=0.0; for (k=1;k<=npg;k++) { wgt=xjac; for (j=1;j<=ndim;j++) { xn=(kg[j]-ran2(&idum))*dxg+1.0; ia[j]=IMAX(IMIN((int)(xn),NDMX),1); if (ia[j] > 1) { xo=xi[j][ia[j]]-xi[j][ia[j]-1]; rc=xi[j][ia[j]-1]+(xn-ia[j])*xo; } else { xo=xi[j][ia[j]]; rc=(xn-ia[j])*xo; } x[j]=regn[j]+rc*dx[j]; wgt *= xo*xnd; } f=wgt*(*fxn)(x,wgt); f2=f*f; fb += f; f2b += f2; for (j=1;j<=ndim;j++) { di[ia[j]][j] += f; if (mds >= 0) d[ia[j]][j] += f2; } } f2b=sqrt(f2b*npg); f2b=(f2b-fb)*(f2b+fb); if (f2b <= 0.0) f2b=TINY; ti += fb; tsi += f2b; if (mds < 0) { for (j=1;j<=ndim;j++) d[ia[j]][j] += f2b; } for (k=ndim;k>=1;k--) { kg[k] %= ng; if (++kg[k] != 1) break; } if (k < 1) break; } tsi *= dv2g; wgt=1.0/tsi; si += wgt*ti; schi += wgt*ti*ti; swgt += wgt; *tgral=si/swgt; *chi2a=(schi-si*(*tgral))/(it-0.9999); if (*chi2a < 0.0) *chi2a = 0.0; *sd=sqrt(1.0/swgt); tsi=sqrt(tsi); if (nprn >= 0) { // printf("%s %3d : integral = %14.7g +/- %9.2g\n", // " iteration no.",it,ti,tsi); // printf("%s integral =%14.7g+/-%9.2g chi**2/IT n = %9.2g\n", // " all iterations: ",*tgral,*sd,*chi2a); if (nprn) { for (j=1;j<=ndim;j++) { // printf(" DATA FOR axis %2d\n",j); // printf("%6s%13s%11s%13s%11s%13s\n", // "X","delta i","X","delta i","X","delta i"); for (i=1+nprn/2;i<=nd;i += nprn+2) { // printf("%8.5f%12.4g%12.5f%12.4g%12.5f%12.4g\n", // xi[j][i],di[i][j],xi[j][i+1], // di[i+1][j],xi[j][i+2],di[i+2][j]); } } } } for (j=1;j<=ndim;j++) { xo=d[1][j]; xn=d[2][j]; d[1][j]=(xo+xn)/2.0; dt[j]=d[1][j]; for (i=2;i<nd;i++) { rc=xo+xn; xo=xn; xn=d[i+1][j]; d[i][j] = (rc+xn)/3.0; dt[j] += d[i][j]; } d[nd][j]=(xo+xn)/2.0; dt[j] += d[nd][j]; } for (j=1;j<=ndim;j++) { rc=0.0; for (i=1;i<=nd;i++) { if (d[i][j] < TINY) d[i][j]=TINY; r[i]=pow((1.0-d[i][j]/dt[j])/ (log(dt[j])-log(d[i][j])),ALPH); rc += r[i]; } rebin(rc/xnd,nd,r,xin,xi[j]); } } }
/** Executes the regroup algorithm * * @throw runtime_error Thrown if */ void Regroup::exec() { // retrieve the properties std::vector<double> rb_params=getProperty("Params"); // Get the input workspace MatrixWorkspace_const_sptr inputW = getProperty("InputWorkspace"); // can work only if all histograms have the same boundaries if (!API::WorkspaceHelpers::commonBoundaries(inputW)) { g_log.error("Histograms with different boundaries"); throw std::runtime_error("Histograms with different boundaries"); } bool dist = inputW->isDistribution(); int histnumber = static_cast<int>(inputW->getNumberHistograms()); MantidVecPtr XValues_new; const MantidVec & XValues_old = inputW->readX(0); std::vector<int> xoldIndex;// indeces of new x in XValues_old // create new output X axis int ntcnew = newAxis(rb_params,XValues_old,XValues_new.access(),xoldIndex); // make output Workspace the same type is the input, but with new length of signal array API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,ntcnew,ntcnew-1); int progress_step = histnumber / 100; if (progress_step == 0) progress_step = 1; for (int hist=0; hist < histnumber;hist++) { // get const references to input Workspace arrays (no copying) const MantidVec& XValues = inputW->readX(hist); const MantidVec& YValues = inputW->readY(hist); const MantidVec& YErrors = inputW->readE(hist); //get references to output workspace data (no copying) MantidVec& YValues_new=outputW->dataY(hist); MantidVec& YErrors_new=outputW->dataE(hist); // output data arrays are implicitly filled by function rebin(XValues,YValues,YErrors,xoldIndex,YValues_new,YErrors_new, dist); outputW->setX(hist,XValues_new); if (hist % progress_step == 0) { progress(double(hist)/histnumber); interruption_point(); } } outputW->isDistribution(dist); // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }
int image2xy_run(simplexy_t* s, int downsample, int downsample_as_required) { int newW, newH; anbool free_fimage = FALSE; // the factor by which to downsample. int S = downsample ? downsample : 1; int jj; anbool tryagain; int rtn = -1; if (downsample && downsample > 1) { logmsg("Downsampling by %i...\n", S); if (!s->image) { s->image = upconvert(s->image_u8, s->nx, s->ny); free_fimage = TRUE; } if (!s->image) goto bailout; rebin(&s->image, s->nx, s->ny, S, &newW, &newH); s->nx = newW; s->ny = newH; } do { simplexy_run(s); tryagain = FALSE; if (s->npeaks == 0 && downsample_as_required) { logmsg("Downsampling by 2...\n"); if (s->image_u8) { s->image = upconvert(s->image_u8, s->nx, s->ny); if (!s->image) goto bailout; free_fimage = TRUE; s->image_u8 = NULL; } rebin(&s->image, s->nx, s->ny, 2, &newW, &newH); s->nx = newW; s->ny = newH; S *= 2; tryagain = TRUE; downsample_as_required--; } } while (tryagain); for (jj=0; jj<s->npeaks; jj++) { assert(isfinite((s->x)[jj])); assert(isfinite((s->y)[jj])); // shift the origin to the FITS standard: // center of the lower-left pixel is (1,1). (s->x)[jj] = ((s->x)[jj] + 0.5) * (double)S + 0.5; (s->y)[jj] = ((s->y)[jj] + 0.5) * (double)S + 0.5; } dselip_cleanup(); rtn = 0; bailout: if (free_fimage) { free(s->image); s->image = NULL; } return rtn; }
/** Calculate a workspace that contains the result of the fit to the * transmission fraction that was calculated * @param raw [in] the workspace with the unfitted transmission ratio data * @param rebinParams [in] the parameters for rebinning * @param fitMethod [in] string can be Log, Linear, Poly2, Poly3, Poly4, Poly5, * Poly6 * @return a workspace that contains the evaluation of the fit * @throw runtime_error if the Linear or ExtractSpectrum algorithm fails during * execution */ API::MatrixWorkspace_sptr CalculateTransmission::fit(API::MatrixWorkspace_sptr raw, std::vector<double> rebinParams, const std::string fitMethod) { MatrixWorkspace_sptr output = this->extractSpectra(raw, std::vector<size_t>(1, 0)); Progress progress(this, m_done, 1.0, 4); progress.report("CalculateTransmission: Performing fit"); // these are calculated by the call to fit below double grad(0.0), offset(0.0); std::vector<double> coeficients; const bool logFit = (fitMethod == "Log"); if (logFit) { g_log.debug("Fitting to the logarithm of the transmission"); MantidVec &Y = output->dataY(0); MantidVec &E = output->dataE(0); double start = m_done; Progress prog2(this, start, m_done += 0.1, Y.size()); for (size_t i = 0; i < Y.size(); ++i) { // Take the log of each datapoint for fitting. Recalculate errors // remembering that d(log(a))/da = 1/a E[i] = std::abs(E[i] / Y[i]); Y[i] = std::log10(Y[i]); progress.report("Fitting to the logarithm of the transmission"); } // Now fit this to a straight line output = fitData(output, grad, offset); } // logFit true else if (fitMethod == "Linear") { // Linear fit g_log.debug("Fitting directly to the data (i.e. linearly)"); output = fitData(output, grad, offset); } else { // fitMethod Polynomial int order = getProperty("PolynomialOrder"); std::stringstream info; info << "Fitting the transmission to polynomial order=" << order; g_log.information(info.str()); output = fitPolynomial(output, order, coeficients); } progress.report("CalculateTransmission: Performing fit"); // if no rebin parameters were set the output workspace will have the same // binning as the input ones, otherwise rebin if (!rebinParams.empty()) { output = rebin(rebinParams, output); } progress.report("CalculateTransmission: Performing fit"); // if there was rebinnning or log fitting we need to recalculate the Ys, // otherwise we can just use the workspace kicked out by the fitData()'s call // to Linear if ((!rebinParams.empty()) || logFit) { const MantidVec &X = output->readX(0); MantidVec &Y = output->dataY(0); if (logFit) { // Need to transform back to 'unlogged' const double m(std::pow(10, grad)); const double factor(std::pow(10, offset)); MantidVec &E = output->dataE(0); for (size_t i = 0; i < Y.size(); ++i) { // the relationship between the grad and interspt of the log fit and the // un-logged value of Y contain this dependence on the X (bin center // values) Y[i] = factor * (std::pow(m, 0.5 * (X[i] + X[i + 1]))); E[i] = std::abs(E[i] * Y[i]); progress.report(); } } // end logFit else if (fitMethod == "Linear") { // the simpler linear situation for (size_t i = 0; i < Y.size(); ++i) { Y[i] = (grad * 0.5 * (X[i] + X[i + 1])) + offset; } } else { // the polynomial fit for (size_t i = 0; i < Y.size(); ++i) { double aux = 0; double x_v = 0.5 * (X[i] + X[i + 1]); for (int j = 0; j < static_cast<int>(coeficients.size()); ++j) { aux += coeficients[j] * std::pow(x_v, j); } Y[i] = aux; } } } progress.report("CalculateTransmission: Performing fit"); return output; }
// Main function to create the pdf's int main(int argc, char**argv){ TString version = "80X"; // Define binning for pdfs (details and more options in binningConfigurations.h) binClass bins; if(version.Contains("v2")) bins = getV2Binning(); if(version.Contains("80X")) bins = get76XBinning(); else return 1; // For different jet types (if _antib is added bTag is applied) for(TString jetType : {"AK4chs","AK4chs_antib"}){ //,"AK4","AK4_antib"}){ std::cout << "Building pdf's for " << jetType << "..." << std::endl; treeLooper t("QCD_AllPtBins", jetType); // Init tree (third argument is the directory path, if other than default in treeLooper.h) bins.setReference("pt", &t.pt); // Give the binning class a pointer to the variables used to bin in bins.setReference("eta", &t.eta); bins.setReference("rho", &t.rho); // Creation of the pdfs std::map<TString, TH1D*> pdfs; for(TString binName : bins.getAllBinNames()){ for(TString type : {"quark","gluon"}){ TString histName = "_" + type + "_" + binName; pdfs["axis2" + histName] = new TH1D("axis2" + histName, "axis2" + histName, 100, 0, 8); // Has been 200 bins before, but seemed to have a bit too much fluctuations still pdfs["mult" + histName] = new TH1D("mult" + histName, "mult" + histName, 140, 2.5, 142.5); pdfs["ptD" + histName] = new TH1D("ptD" + histName, "ptD" + histName, 100, 0, 1); // Also 200 before } } // Fill pdfs TString binName; while(t.next()){ if(!bins.getBinName(binName)) continue; // Find bin and return false if outside ranges if(t.jetIdLevel < 3) continue; // Select tight jets if(!t.matchedJet) continue; // Only matched jets if(t.nGenJetsInCone != 1 || t.nJetsForGenParticle != 1 || t.nGenJetsForGenParticle != 1) continue; // Use only jets matched to exactly one gen jet and gen particle, and no other jet candidates if((fabs(t.partonId) > 3 && t.partonId != 21)) continue; // Keep only udsg if(t.bTag) continue; // Anti-b tagging (always false if jetType does not contain "antib") if(!t.balanced) continue; // Take only two leading jets with pt3 < 0.15*(pt1+pt2) (surpresses small radiated jets with pt <<< pthat) if(t.mult < 3) continue; // Avoid jets with less than 3 particles (otherwise axis2=0) TString type = (t.partonId == 21? "gluon" : "quark"); // Define q/g TString histName = "_" + type + "_" + binName; pdfs["axis2" + histName]->Fill(t.axis2, t.weight); // "axis2" already contains the log pdfs["mult" + histName]->Fill(t.mult, t.weight); pdfs["ptD" + histName]->Fill(t.ptD, t.weight); } // Try to add statistics from neighbours (first make copy, so you don't get an iterative effect) std::map<TString, TH1D*> pdfsCopy; for(auto& pdf : pdfs) pdfsCopy[pdf.first] = (TH1D*) pdf.second->Clone(pdf.first + "clone"); for(TString binName : bins.getAllBinNames()){ for(TString var : {"axis2","mult","ptD"}){ for(TString neighbour : bins.getNeighbourBins(binName, var)){ // If neighbours are defined: add their statistics for(TString type : {"quark","gluon"}){ pdfs[var + "_" + type + "_" + binName]->Add(pdfsCopy[var + "_" + type + "_" + neighbour]); } } } } for(auto& copy : pdfsCopy) delete copy.second; // Store the mean and RMS of the original histogram (because they could be changed by rebinning operations) std::map<TString, float> mean; std::map<TString, float> rms; for(auto& pdf : pdfs){ if(pdf.second->GetEntries() == 0){ std::cout << "Error: no entries in " << pdf.first << std::endl; exit(1);} // Force to exit when no entries in pdfs: the binning configuration should be altered to avoid this mean[pdf.first] = pdf.second->GetMean(); rms[pdf.first] = pdf.second->GetRMS(); } // Check "smoothness" of the pdf: if fluctuations seem really big, we do a rebinning std::map<TString, int> rebinFactor; for(auto& pdf : pdfs){ bool isBelow = (mean[pdf.first] < mean[switchQG(pdf.first)]); // Define region between low(meanQ, meanG) - RMS <--> high(meanQ, meanG) + RMS TString low = isBelow? pdf.first : switchQG(pdf.first); // Most events will be within those borders, so we should not allow empty bins here TString high = isBelow? switchQG(pdf.first) : pdf.first; // (an empty bin for 1 of the three variables already results in L = 0 or 1) int leftBin = pdf.second->FindBin(mean[low] - rms[low]) - 1; int rightBin = pdf.second->FindBin(mean[high] + rms[high]) + 1; int leftBin2 = 0; // Define region of the peak: most extreme bins which exceed 80% of the maximum int rightBin2 = 0; // We will check for bins within this region which go below 70% for(int bin = 1; bin < pdf.second->GetNbinsX(); ++bin){ // In such cases the fluctuations are really high and a larger bin width is preferred if(pdf.second->GetBinContent(bin) > pdf.second->GetMaximum()*0.8){ // (Maybe the thresholds could still be optimized a bit more though) if(!leftBin2) leftBin2 = bin; else rightBin2 = bin; } } int leftBin3 = 0; // Define region of the peak: most extreme bins which exceed 90% of the maximum int rightBin3 = 0; // We will check for bins within this region which go below 80% for(int bin = 1; bin < pdf.second->GetNbinsX(); ++bin){ // In such cases the fluctuations are really high and a larger bin width is preferred if(pdf.second->GetBinContent(bin) > pdf.second->GetMaximum()*0.9){ // (Maybe the thresholds could still be optimized a bit more though) if(!leftBin3) leftBin3 = bin; else rightBin3 = bin; } } int emptyBins = 0; int maxEmptyBins = 0; for(int bin = 1; bin < pdf.second->GetNbinsX(); ++bin){ if( bin >= leftBin && bin <= rightBin && pdf.second->GetBinContent(bin) <= 0) ++emptyBins; else if(bin >= leftBin2 && bin <= rightBin2 && pdf.second->GetBinContent(bin) <= pdf.second->GetMaximum()*0.7) ++emptyBins; else if(bin >= leftBin3 && bin <= rightBin3 && pdf.second->GetBinContent(bin) <= pdf.second->GetMaximum()*0.8) ++emptyBins; else { if(emptyBins > maxEmptyBins) maxEmptyBins = emptyBins; emptyBins = 0; } } rebinFactor[pdf.first] = std::max(maxEmptyBins, emptyBins); } for(auto& pdf : pdfs) rebinFactor[pdf.first] = std::max(rebinFactor[pdf.first], rebinFactor[switchQG(pdf.first)]); // Use same rebin factor in quark and gluon pdf (otherwise bias if second derivate of pdf is non-zero) for(auto& pdf : pdfs){ if(rebinFactor[pdf.first] > 19) std::cout << "This pdf has a lot of emtpy bins and fluctuations:" << std::endl; if(rebinFactor[pdf.first] > 9) rebin(pdf.second, 20); else if(rebinFactor[pdf.first] > 4) rebin(pdf.second, 10); else if(rebinFactor[pdf.first] > 3) rebin(pdf.second, 5); else if(rebinFactor[pdf.first] > 1) rebin(pdf.second, 4); else if(rebinFactor[pdf.first] > 0) rebin(pdf.second, 2); } // Normalization of the pdf's for(auto& pdf : pdfs) pdf.second->Scale(1./pdf.second->Integral(0, pdf.second->GetNbinsX() + 1)); // Scale to integral=1 (also include underflow/overflow) // Try to average out leftover fluctuations and empty bins for(auto& pdf : pdfs){ if(pdf.first.Contains("gluon")) continue; TH1* tempQ = (TH1*) pdf.second->Clone(); TH1* tempG = (TH1*) pdfs[switchQG(pdf.first)]->Clone(); for(int i = 1; i < pdf.second->GetNbinsX() + 1; ++i){ // Do not consider underflow/overflow float contentQ = tempQ->GetBinContent(i); float contentG = tempG->GetBinContent(i); float width = tempQ->GetBinWidth(i); if((1.5*contentQ < tempQ->GetBinContent(i-1) && 1.5*contentQ < tempQ->GetBinContent(i+1)) || // Try to average out some extreme fluctuations (i.e. only allow a difference of max 50% between two neighbouring bins) (1.5*contentG < tempG->GetBinContent(i-1) && 1.5*contentG < tempG->GetBinContent(i+1)) || (contentQ < 1.5*tempQ->GetBinContent(i-1) && contentQ < 1.5*tempQ->GetBinContent(i+1)) || (contentG < 1.5*tempG->GetBinContent(i-1) && contentG < 1.5*tempG->GetBinContent(i+1))){ if(i-1 > 0 && i+1 < pdf.second->GetNbinsX() + 1){ contentQ += tempQ->GetBinContent(i-1) + tempQ->GetBinContent(i+1); contentG += tempG->GetBinContent(i-1) + tempG->GetBinContent(i+1); width += tempQ->GetBinWidth(i-1) + tempQ->GetBinWidth(i+1); } } int j = 1; while(contentQ <= 0 || contentG <= 0){ // Average empty bins if(tempQ->Integral(0, i-j) <= 0) break; // but not when surpassing the extreme edges of the pdf (see next part) if(tempG->Integral(0, i-j) <= 0) break; if(tempQ->Integral(i+j, tempQ->GetNbinsX()+1) <= 0) break; if(tempG->Integral(i+j, tempG->GetNbinsX()+1) <= 0) break; if(i-j == 0) break; if(i+j == pdf.second->GetNbinsX()) break; contentQ += tempQ->GetBinContent(i-j) + tempQ->GetBinContent(i+j); contentG += tempG->GetBinContent(i-j) + tempG->GetBinContent(i+j); width += tempQ->GetBinWidth(i-j) + tempQ->GetBinWidth(i+j); ++j; } pdf.second->SetBinContent(i, contentQ/width); pdfs[switchQG(pdf.first)]->SetBinContent(i, contentG/width); } delete tempQ; delete tempG; } // Now there are still empty bins left on the edges of the pdf, for which we assign extreme values to avoid a 0 // (relative though, so it does not dominate the pdf's when we want to inspect them in the ROOT file; 0.000001/0.000999 has the same effect as 0.001/0.999) for(auto& pdf : pdfs){ if(pdf.first.Contains("gluon")) continue; for(int i = 0; i <= pdf.second->GetNbinsX() + 1; ++i){ if(pdf.second->GetBinContent(i) <= 0 || pdfs[switchQG(pdf.first)]->GetBinContent(i) <= 0){ bool isBelow = (mean[pdf.first] < mean[switchQG(pdf.first)]); if(isBelow == pdf.second->GetBinCenter(i) < mean[pdf.first]){ pdf.second->SetBinContent(i, 0.000999); pdfs[switchQG(pdf.first)]->SetBinContent(i, 0.000001); } else { pdf.second->SetBinContent(i, 0.000001); pdfs[switchQG(pdf.first)]->SetBinContent(i, 0.000999); } } } } // Apply the likelihood weight for(auto& pdf : pdfs){ TString thisBin = pdf.first(pdf.first.Index(TRegexp("eta")), pdf.first.Length()); TString thisVar = pdf.first(0, pdf.first.Index(TRegexp("_"))); for(int i = 0; i < pdf.second->GetNbinsX() + 1; ++i){ pdf.second->SetBinContent(i, std::pow(pdf.second->GetBinContent(i), bins.getWeight(thisBin, (thisVar == "mult"? 0 : (thisVar == "ptD" ? 1 : 2 ))))); } } // Make file and write binnings TFile *pdfFile = new TFile("pdfQG_"+jetType + "_13TeV_" + version + ".root","RECREATE"); pdfFile->cd(); bins.writeBinsToFile(); // Write to file for(TString var : {"axis2","ptD","mult"}) pdfFile->mkdir(var); for(auto& pdf : pdfs){ for(TString var: {"axis2","ptD","mult"}) if(pdf.first.Contains(var)) pdfFile->cd(var); pdf.second->SetTitle(pdf.first); pdf.second->Write(); TString thisBin = pdf.first(pdf.first.Index(TRegexp("eta")), pdf.first.Length()); for(auto i : bins.getLinkedBins(thisBin)){ // Store copies for merged bins TString copyBin = pdf.first; copyBin.ReplaceAll(thisBin, i); pdf.second->Write(copyBin); } } for(auto& pdf : pdfs) delete pdf.second; for(auto& file : {pdfFile}){ file->Close(); delete file;} } return 0; }
/* MARKUS: weight wgt has been added to the argument list of fxn*/ void vegas_mpi_(double regn[], int *ndim_in, void (*fxn)(double x[], double *wgt,double f[]), int *init_in, int *ncall_in, int *itmx_in, int *nprn_in, int *fcns_in, int *pdim_in, int *wrks_in, double tgral[], double sd[], double chi2a[]) { int ndim,init,ncall,itmx,nprn,fcns,pdim,wrks; static int ndo; /* (ndo) */ int it; /* iteration counter (it) */ static int ittot; /* iteration counter across init>1 */ double calls; /* real total number of calls to fxn (calls) */ double dv2g; /* (dv2g) */ double xin[NDMX]; /* aux. variable for rebinning (xin[]) */ typedef struct { double Wgt; /* weight (wgt) */ double sWgt; /* cumulative sum for weights (swgt) */ double sChi; /* cumulative sum for chi^2 (schi) */ double sInt; /* cumulative sum for integral (si) */ } iterAccu; /* accumulator for stuff at end of iteration... */ static iterAccu Ai[FNMX]; /* ...one for each integrand */ double dt[MXDIM]; /* (dt[]) */ double r[NDMX]; /* (r[]) */ int i, j, k; /* counters (i, j, k) */ int whodunit; /* who returned the result to master? */ double rc; /* (rc) */ double xn; /* (xn) */ double xo; /* (xo) */ double wgt; /* weight (wgt) */ int wmax; /* for computing limit, if wrks too large */ ndim=(*ndim_in); /* MARKUS: restoring original arguments */ init=(*init_in); ncall=(*ncall_in); itmx=(*itmx_in); nprn=(*nprn_in); fcns=(*fcns_in); pdim=(*pdim_in); wrks=(*wrks_in); ReducedCHistogram CMasterHisto[NUMHISTO]; /* MARKUS: these are the master histograms containing results from all slaves */ // printf("\n arg check %10.4f %10.4f %10.4f %10.4f \n",regn[0],regn[2],regn[1],regn[3]); // printf("\n arg check %i %i %i %i %i \n",ndim,init,ncall,itmx,wrks); MPI_Status recv_status; #if (REPRO != 0) unsigned long i_rep; /* number of RNs to skip */ #endif MPI_Comm_rank(MPI_COMM_WORLD, &p_rank); // gets the rank MPI_Comm_size(MPI_COMM_WORLD, &p_size); // gets the number of nodes // MARKUS: define MPI_HISTO for receiving C histogram structs MPI_Datatype MPI_HISTO, oldtypes[2]; int blockcounts[2]; MPI_Aint offsets[2], extent; offsets[0] = 0; oldtypes[0] = MPI_DOUBLE; blockcounts[0] = 2*MXHISTOBINS; MPI_Type_extent(MPI_DOUBLE, &extent); offsets[1] = blockcounts[0] * extent; oldtypes[1] = MPI_INT; blockcounts[1] = 1*MXHISTOBINS; MPI_Type_struct(2, blockcounts, offsets, oldtypes, &MPI_HISTO); MPI_Type_commit(&MPI_HISTO); wrks = (wrks<1) ? 1 : ((MXWORK<wrks) ? MXWORK : wrks); if (wrks>=p_size) wrks = p_size-1; gndim = ndim; if (NDIM_PAR == 0) ndim_par = ndim/2; else ndim_par = NDIM_PAR; functions = (fcns<FNMX) ? (fcns) : (FNMX); for (i=0; i<ndim_par; i++) kgl[i] = 1; p_fxn = fxn; for (j=0; j<ndim; j++) gregn[j] = regn[j]; #if (REPRO != 0) if (gfsr_not_initialized) gfsr_init(REPRO); #else if (gfsr_not_initialized) gfsr_init((long)time(NULL)); #endif if (init <= 0) { /* entry for cold start */ mds = ndo = 1; /* Careful with that Axe, Eugene! */ /* mds=0 will trash parallelization. */ for (j=0; j<ndim; j++) xi[j][0] = 1.0; } if (init <= 1) { /* inherit the previous grid */ for (j=0; j<functions; j++) { Ai[j].sInt = 0.0; Ai[j].sWgt = 0.0; Ai[j].sChi = 0.0; } ittot = 1; } if (init <= 2) { /* inherit grid and results */ nd = NDMX; ng = 1; if (mds) { ng = (int)pow(ncall/2.0+0.25,1.0/ndim); if( ng==1 ) printf("WARNING: ng=1! You might want to increase ncall.\n"); // printf("MARKUS: nodes: %i %20.9f\n",ng,pow(ncall/2.0+0.25,1.0/ndim)); // MARKUS:: if workers is forced one, then ng is probably one. increase ncall! mds = 1; if ((2*ng-NDMX) >= 0) { mds = -1; npg = ng/NDMX+1; nd = ng/npg; ng = npg*nd; } } wmax = 1; for (i=0; i<ndim_par; i++) wmax *= ng; if (wrks>wmax) wrks = wmax; for (k=1,i=0; i<ndim; i++) k *= ng; npg = (ncall/k>2) ? (ncall/k) : (2); calls = (double)npg * (double)k; dxg = 1.0/ng; for (dv2g=1,i=0; i<ndim; i++) dv2g *= dxg; dv2g = calls*calls*dv2g*dv2g/npg/npg/(npg-1.0); xnd = nd; dxg *= xnd; xJac = 1.0/calls; for (j=0; j<ndim; j++) { dx[j] = regn[j+ndim]-regn[j]; xJac *= dx[j]; } if (nd != ndo) { for (i=0; i<(nd>ndo?nd:ndo); i++) r[i] = 1.0; for (j=0; j<ndim; j++) rebin(ndo/xnd,nd,r,xin,xi[j]); ndo = nd; } if (!p_rank && nprn & NPRN_INPUT) { printf("%s: ndim= %3d ncall= %8.0f %3d+1/%3d CPU(s)\n", "\n\n Input parameters for vegas",ndim,calls,wrks,p_size); printf("%28s ittot=%5d itmx=%5d %5d^%1d hypercubes\n"," ",ittot,itmx,ng,ndim_par); printf("%28s nprn=0x%04x ALPH=%5.2f\n"," ",nprn,ALPH); printf("%28s mds=%3d nd=%4d%15s npg=%d\n"," ",mds,nd," ",npg); for (j=0; j<ndim; j++) { printf("%30s xl[%2d]= %11.4g xu[%2d]= %11.4g\n", " ",j,regn[j],j,regn[j+ndim]); } } } ReducedCHistogram CHisto_tmp[NUMHISTO]; /* MARKUS: temporary histograms from the slaves */ ReducedCHistogram CHisto_tmp2[NUMHISTO]; /* MARKUS: temporary histograms to sum up the slave histograms */ for (j=0; j<NUMHISTO; j++) { /* MARKUS: initialize C master histograms */ for (i=0; i<MXHISTOBINS; i++) { CMasterHisto[j].Value[i]=0.0; CMasterHisto[j].Value2[i]=0.0; CMasterHisto[j].Hits[i]=0; } } /* ========== begin iterations ========== */ for (it=ittot; it<=itmx+ittot-1; it++) { /* starting the iteration loop */ kgl[0] = 1; /* kgl[0] is also used to determine if we are done yet */ for (i=0; i<ndim_par; i++) if (kgl[i]!=1) { kgl[i] = 1; } for (j=0; j<functions; j++) { Ab[j].ti = Ab[j].tsi = 0.0; } for (j=0; j<gndim; j++) { for (i=0; i<nd; i++) d[i][j] = di[i][j] = 0.0; } if (p_rank == 0) { /* ============= master ============= */ do { MPI_Recv(&whodunit, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &recv_status); for (j=0; j<ndim_par; j++) kgl_buf[j] = kgl[j]; MPI_Send(kgl_buf, ndim_par, MPI_INT, whodunit, 0, MPI_COMM_WORLD); for (j=ndim_par; j>=1; j--) { kgl[j-1] %= ng; if (++kgl[j-1] != 1) break; } if (j < 1) kgl[0] = 0; /* we are done! */ } while (kgl[0] != 0); /* Send a final kgl (zeroed) to everyone */ for (j=1; j<=wrks; j++) { MPI_Send(&kgl, ndim_par, MPI_INT, j, 0, MPI_COMM_WORLD); } for (j=0; j<NUMHISTO; j++) { /* MARKUS: empty C temp histograms in each iteration*/ for (i=0; i<MXHISTOBINS; i++) { CHisto_tmp2[j].Value[i] = 0.0; CHisto_tmp2[j].Value2[i] = 0.0; CHisto_tmp2[j].Hits[i] = 0; }; }; /* Now wait for all the results to come in */ for (k=0; k<wrks; k++) { // MARKUS: Require to receive from rank k+1. This means that we have to wait until k is finished before receiving from k+1. But we have to wait for all of them anyways. MPI_Recv(&result_buf, (2*functions + 2*(gndim*nd)), MPI_DOUBLE, k+1, 1, MPI_COMM_WORLD, &recv_status); MPI_Recv(CHisto_tmp,NUMHISTO,MPI_HISTO,k+1,2,MPI_COMM_WORLD, &recv_status); /* MARKUS: receive array of C histogram structs */ if( k==0 ) { printf(" Master has received histograms from workers %i",k+1); } else { printf(", %i",k+1); }; if( k==wrks-1 ) printf("\n"); for (j=0; j<NUMHISTO; j++) { /* MARKUS: Sum histograms from slaves and save in CHisto_tmp2 */ for (i=0; i<MXHISTOBINS; i++) { CHisto_tmp2[j].Value[i] += CHisto_tmp[j].Value[i]; CHisto_tmp2[j].Value2[i] += CHisto_tmp[j].Value2[i]; CHisto_tmp2[j].Hits[i] += CHisto_tmp[j].Hits[i]; }; }; for (j=0; j<functions; j++) /* disassemble result_buf */ Ab[j].ti += result_buf[j]; for (j=0; j<functions; j++) Ab[j].tsi += result_buf[j+functions]; for (j=0; j<gndim; j++) { for (i=0; i<nd; i++) d[i][j] += result_buf[2*functions + j*nd + i]; for (i=0; i<nd; i++) di[i][j] += result_buf[2*functions + gndim*nd + j*nd + i]; } } for (j=0; j<functions; j++) /* assemble the send-buffer */ result_buf[j] = Ab[j].ti; for (j=0; j<functions; j++) result_buf[j+functions] = Ab[j].tsi; for (j=0; j<gndim; j++) { for (i=0; i<nd; i++) result_buf[2*functions + j*nd + i] = d[i][j]; for (i=0; i<nd; i++) result_buf[2*functions + gndim*nd + j*nd + i] = di[i][j]; } for (j=1; j<p_size; j++) { MPI_Send(&result_buf, (2*functions + 2*(ndim*nd)), MPI_DOUBLE, j, 2, MPI_COMM_WORLD); } for (j=0; j<NUMHISTO; j++) { /* MARKUS: Save results of this iteration in the master histograms */ for (i=0; i<MXHISTOBINS; i++) { CMasterHisto[j].Value[i] = CMasterHisto[j].Value[i] + CHisto_tmp2[j].Value[i] ; CMasterHisto[j].Value2[i]= CMasterHisto[j].Value2[i] + CHisto_tmp2[j].Value2[i]; CMasterHisto[j].Hits[i] += CHisto_tmp2[j].Hits[i]; }; int NHisto=j+1; modkinematics_mp_transferhisto_(&CMasterHisto[j],&NHisto); /* MARKUS: Send it to TOPAZ */ }; // printf("Printing final CMAsterHistograms"); // for (j=0; j<NUMHISTO; j++) { // for (i=0; i<MXHISTOBINS; i++) { // printf(" %i %i %20.8e \n",j+1,i+1,CMasterHisto[j].Value[i]); // }; // }; } /* end master */ else { /* ============= slave ============= */ modkinematics_mp_clearredhisto_(); /* MARKUS: Empty fortran histograms in each iteration */ if (p_rank<=wrks) p_vegasloop(NULL); #if (REPRO != 0) /* Now advance the remaining RNGs in case the */ if (p_rank>wrks) { /* next call runs on more CPUs */ for (i_rep=0;i_rep<calls*ndim;i_rep++) gfsr_rand(gfsr_m,&gfsr_k); } #endif MPI_Recv(&result_buf, (2*functions + 2*(ndim*nd)), MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, &recv_status); for (j=0; j<functions; j++) /* disassemble result_buf */ Ab[j].ti = result_buf[j]; for (j=0; j<functions; j++) Ab[j].tsi = result_buf[j+functions]; for (j=0; j<gndim; j++) { for (i=0; i<nd; i++) d[i][j] = result_buf[2*functions + j*nd + i]; for (i=0; i<nd; i++) di[i][j] = result_buf[2*functions + gndim*nd + j*nd + i]; } } /* end slave */ for (j=0; j<functions; j++) { Ab[j].tsi *= dv2g; Ai[j].Wgt = 1.0/Ab[j].tsi; Ai[j].sInt += Ai[j].Wgt*Ab[j].ti; Ai[j].sChi += Ai[j].Wgt*Ab[j].ti*Ab[j].ti; Ai[j].sWgt += Ai[j].Wgt; tgral[j] = Ai[j].sInt/Ai[j].sWgt; chi2a[j] = (Ai[j].sChi-Ai[j].sInt*tgral[j])/(it-0.9999); if (chi2a[j] < 0.0) chi2a[j] = 0.0; sd[j] = sqrt(1.0/Ai[j].sWgt); Ab[j].tsi = sqrt(Ab[j].tsi); } wgt = Ai[0].Wgt; if (!p_rank && nprn & NPRN_RESULT) { printf("%s %3d : integral = %16.7e +/- %13.4e\n", " iteration no.",it,Ab[0].ti,Ab[0].tsi); printf("%s integral = %16.7e +/- %13.4e chi^2/it = %9.2g\n", " all iterations: ",tgral[0],sd[0],chi2a[0]); } #if ( _WriteTmpHisto==1 ) if( !p_rank ) { double time=0.0; int histounit=14,itfix=1; // printf("Writing intermediate histograms \n"); writehisto_(&histounit,&it,&Ab[0].ti,&Ab[0].tsi,&tgral[0],&sd[0],&chi2a[0],&time); }; #endif if (!p_rank && nprn & NPRN_SECRES) { for (i=1; i<functions; i++) { printf(" %4d%s%14.7g +/-%9.2g chi^2/it = %9.2g\n", i,".additional integral= ",tgral[i],sd[i],chi2a[i]); } } if (!p_rank && nprn & (NPRN_GRID | NPRN_GRID_2 | NPRN_GRID_4 | NPRN_GRID_8)) { for (j=0; j<ndim; j++) { printf(" data for axis %2d\n",j); printf("%6s%13s%11s%13s%11s%13s\n", "X","delta i","X","delta i","X","delta i"); for (i=0; i<nd; i += 3) { for (k=0; k<3 && i+k<nd; k++) { printf("%8.5f%12.4g ",xi[j][i+k],di[i+k][j]); } printf("\n"); if (nprn & NPRN_GRID_8) k = 3*(8-1); if (nprn & NPRN_GRID_4) k = 3*(4-1); if (nprn & NPRN_GRID_2) k = 3*(2-1); if (nprn & NPRN_GRID) k = 3*(1-1); i += k; } } } if (!p_rank ) printf("\n"); for (j=0; j<ndim; j++) { xo = d[0][j]; xn = d[1][j]; d[0][j] = (xo+xn)/2.0; dt[j] = d[0][j]; for (i=1; i<nd-1; i++) { rc = xo+xn; xo = xn; xn = d[i+1][j]; d[i][j] = (rc+xn)/3.0; dt[j] += d[i][j]; } d[nd-1][j] = (xo+xn)/2.0; dt[j] += d[nd-1][j]; } for (j=0; j<ndim; j++) { rc = 0.0; for (i=0; i<nd; i++) { if (d[i][j] < TINY) d[i][j] = TINY; r[i] = pow((1.0-d[i][j]/dt[j])/ (log(dt[j])-log(d[i][j])),ALPH); rc += r[i]; } rebin(rc/xnd,nd,r,xin,xi[j]); } } /* ========== end iterations ========== */ ittot += itmx; return; }
void addNuisanceWithToys(std::string iFileName,std::string iChannel,std::string iBkg,std::string iEnergy,std::string iName,std::string iDir,bool iRebin=true,bool iVarBin=false,int iFitModel=1,int iFitModel1=1,double iFirst=150,double iLast=1500,std::string iSigMass="800",double iSigScale=0.1,int iNToys=1000) { std::cout << "======> " << iDir << "/" << iBkg << " -- " << iFileName << std::endl; if(iVarBin) std::cout << "option not implemented yet!"; if(iVarBin) return; //double lFirst = 200; //double lLast = 1500; double lFirst = iFirst; double lLast = iLast; std::cout << "===================================================================================================================================================" <<std::endl; std::cout << "Using Initial fit model: " << iFitModel << ", fitting range: " << iFirst << "-" << iLast << " , using alternative fit model: " << iFitModel1 << std::endl; std::cout << "===================================================================================================================================================" <<std::endl; TFile *lFile = new TFile(iFileName.c_str()); TH1F *lH0 = (TH1F*) lFile->Get((iDir+"/"+iBkg).c_str()); TH1F *lData = (TH1F*) lFile->Get((iDir+"/data_obs").c_str()); TH1F *lSig = 0; // for now, use bbH signal for testing in b-tag and ggH in no-btag if(iDir.find("_btag") != std::string::npos) lSig = (TH1F*)lFile->Get((iDir+"/bbH"+iSigMass+"_fine_binning").c_str()); else lSig = (TH1F*)lFile->Get((iDir+"/ggH"+iSigMass+"_fine_binning").c_str()); TH1F *lH0Clone = (TH1F*)lH0->Clone("lH0Clone"); // binning too fine as of now? start by rebinning TH1F *lDataClone = (TH1F*)lData->Clone("lDataClone"); TH1F *lSigClone = (TH1F*)lSig->Clone("lSigClone"); // lH0Clone->Rebin(2); // lDataClone->Rebin(2); // lSigClone->Rebin(2); lSig->Rebin(10); //Define the fit function RooRealVar lM("m","m" ,0,5000); lM.setRange(lFirst,lLast); RooRealVar lA("a","a" ,50, 0.1,200); RooRealVar lB("b","b" ,0.0 , -10.5,10.5); RooRealVar lA1("a1","a1" ,50, 0.1,1000); RooRealVar lB1("b1","b1" ,0.0 , -10.5,10.5); RooDataHist *pH0 = new RooDataHist("Data","Data" ,RooArgList(lM),lH0); double lNB0 = lH0->Integral(lH0->FindBin(lFirst),lH0->FindBin(lLast)); double lNSig0 = lSig->Integral(lSig->FindBin(lFirst),lSig->FindBin(lLast)); //lNB0=500; // lNSig0=500; lSig->Scale(iSigScale*lNB0/lNSig0); // scale signal to iSigScale*(Background yield), could try other options lNSig0 = lSig->Integral(lSig->FindBin(lFirst),lSig->FindBin(lLast)); // readjust norm of signal hist //Generate the "default" fit model RooGenericPdf *lFit = 0; lFit = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB)); if(iFitModel == 1) lFit = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB)); if(iFitModel == 1) {lA.setVal(0.3); lB.setVal(0.5);} if(iFitModel == 2) lFit = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB)); if(iFitModel == 2) {lA.setVal(0.01); lA.setRange(0,10); } if(iFitModel == 3) lFit = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB)); // Generate the alternative model RooGenericPdf *lFit1 = 0; lFit1 = new RooGenericPdf("genPdf","exp(-m/(a1+b1*m))",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 1) lFit1 = new RooGenericPdf("genPdf","exp(-a1*pow(m,b1))",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 1) {lA1.setVal(0.3); lB1.setVal(0.5);} if(iFitModel1 == 2) lFit1 = new RooGenericPdf("genPdf","a1*exp(b1*m)",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 2) {lA1.setVal(0.01); lA1.setRange(0,10); } if(iFitModel1 == 3) lFit1 = new RooGenericPdf("genPdf","a1/pow(m,b1)",RooArgList(lM,lA1,lB1)); //============================================================================================================================================= //Perform the tail fit and generate the shift up and down histograms //============================================================================================================================================= RooFitResult *lRFit = 0; lRFit = lFit->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast),RooFit::Strategy(0)); TMatrixDSym lCovMatrix = lRFit->covarianceMatrix(); TMatrixD lEigVecs(2,2); lEigVecs = TMatrixDSymEigen(lCovMatrix).GetEigenVectors(); TVectorD lEigVals(2); lEigVals = TMatrixDSymEigen(lCovMatrix).GetEigenValues(); cout << " Ve---> " << lEigVecs(0,0) << " -- " << lEigVecs(1,0) << " -- " << lEigVecs(0,1) << " -- " << lEigVecs(1,1) << endl; cout << " Co---> " << lCovMatrix(0,0) << " -- " << lCovMatrix(1,0) << " -- " << lCovMatrix(0,1) << " -- " << lCovMatrix(1,1) << endl; double lACentral = lA.getVal(); double lBCentral = lB.getVal(); lEigVals(0) = sqrt(lEigVals(0)); lEigVals(1) = sqrt(lEigVals(1)); cout << "===> " << lEigVals(0) << " -- " << lEigVals(1) << endl; TH1F* lH = (TH1F*) lFit->createHistogram("fit" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral + lEigVals(0)*lEigVecs(0,0)); lB.setVal(lBCentral + lEigVals(0)*lEigVecs(1,0)); TH1F* lHUp = (TH1F*) lFit->createHistogram("Up" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral - lEigVals(0)*lEigVecs(0,0)); lB.setVal(lBCentral - lEigVals(0)*lEigVecs(1,0)); TH1F* lHDown = (TH1F*) lFit->createHistogram("Down",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral + lEigVals(1)*lEigVecs(0,1)); lB.setVal(lBCentral + lEigVals(1)*lEigVecs(1,1)); TH1F* lHUp1 = (TH1F*) lFit->createHistogram("Up1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral - lEigVals(1)*lEigVecs(0,1)); lB.setVal(lBCentral - lEigVals(1)*lEigVecs(1,1)); TH1F* lHDown1 = (TH1F*) lFit->createHistogram("Down1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); std::string lNuisance1 = iBkg+"_"+"CMS_"+iName+"1_" + iChannel + "_" + iEnergy; std::string lNuisance2 = iBkg+"_"+"CMS_"+iName+"2_" + iChannel + "_" + iEnergy; lHUp = merge(lNuisance1 + "Up" ,lFirst,lH0,lHUp); lHDown = merge(lNuisance1 + "Down" ,lFirst,lH0,lHDown); lHUp1 = merge(lNuisance2 + "Up" ,lFirst,lH0,lHUp1); lHDown1 = merge(lNuisance2 + "Down" ,lFirst,lH0,lHDown1); lH = merge(lH0->GetName() ,lFirst,lH0,lH); //============================================================================================================================================= //============================================================================================================================================= //Set the variables A and B to the final central values from the tail fit lA.setVal(lACentral); lB.setVal(lBCentral); // lA.removeRange(); // lB.removeRange(); //Generate the background pdf corresponding to the final result of the tail fit RooGenericPdf *lFitFinal = 0; lFitFinal = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB)); if(iFitModel == 1) lFitFinal = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB)); if(iFitModel == 2) lFitFinal = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB)); if(iFitModel == 3) lFitFinal = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB)); //============================================================================================================================================= //Perform the tail fit with the alternative fit function (once initially, before allowing tail fit to float in toy fit). //============================================================================================================================================= RooFitResult *lRFit1 = 0; //lRFit1=lFit1->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(iFirst,iLast),RooFit::Strategy(0)); lRFit1=lFit1->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(200,1500),RooFit::Strategy(0)); //Generate the background pdf corresponding to the result of the alternative tail fit RooGenericPdf *lFit1Final = 0; lFit1Final = new RooGenericPdf("genPdf","exp(-m/(a1+b1*m))",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 1) lFit1Final = new RooGenericPdf("genPdf","exp(-a1*pow(m,b1))",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 2) lFit1Final = new RooGenericPdf("genPdf","a1*exp(b1*m)",RooArgList(lM,lA1,lB1)); if(iFitModel1 == 3) lFit1Final = new RooGenericPdf("genPdf","a1/pow(m,b1)",RooArgList(lM,lA1,lB1)); // lA1.removeRange(); // lB1.removeRange(); //============================================================================================================================================= //Define RooRealVar for the normalization of the signal and background, starting from the initial integral of the input histograms lM.setRange(300,1500); RooRealVar lNB("nb","nb",lNB0,0,10000); RooRealVar lNSig("nsig","nsig",lNSig0,-1000,1000); //Define a PDF for the signal histogram lSig RooDataHist *pS = new RooDataHist("sigH","sigH",RooArgList(lM),lSig); RooHistPdf *lSPdf = new RooHistPdf ("sigPdf","sigPdf",lM,*pS); //Define generator and fit functions for the RooMCStudy RooAddPdf *lGenMod = new RooAddPdf ("genmod","genmod",RooArgList(*lFitFinal ,*lSPdf),RooArgList(lNB,lNSig)); RooAddPdf *lFitMod = new RooAddPdf ("fitmod","fitmod",RooArgList(*lFit1Final,*lSPdf),RooArgList(lNB,lNSig)); //Generate plot of the signal and background models going into the toy generation RooPlot* plot=lM.frame(); lGenMod->plotOn(plot); lGenMod->plotOn(plot,RooFit::Components(*lSPdf),RooFit::LineColor(2)); TCanvas* lC11 = new TCanvas("pdf","pdf",600,600) ; lC11->cd(); plot->Draw(); lC11->SaveAs(("SBModel_"+iBkg+"_" + iDir + "_" + iEnergy+".pdf").c_str()); std::cout << "===================================================================================================================================================" <<std::endl; std::cout << "FIT PARAMETERS BEFORE ROOMCSTUDY: lA: " << lA.getVal() << " lB: " << lB.getVal() << " lA1: " << lA1.getVal() << " lB1: " << lB1.getVal() << std::endl; std::cout << "===================================================================================================================================================" <<std::endl; RooMCStudy *lToy = new RooMCStudy(*lGenMod,lM,RooFit::FitModel(*lFitMod),RooFit::Binned(kTRUE),RooFit::Silence(),RooFit::Extended(kTRUE),RooFit::Verbose(kTRUE),RooFit::FitOptions(RooFit::Save(kTRUE),RooFit::Strategy(0))); // Generate and fit iNToys toy samples std::cout << "Number of background events: " << lNB0 << " Number of signal events: " << lNSig0 << " Sum: " << lNB0+lNSig0 << std::endl; //============================================================================================================================================= // Generate and fit toys //============================================================================================================================================= lToy->generateAndFit(iNToys,lNB0+lNSig0,kTRUE); std::cout << "===================================================================================================================================================" <<std::endl; std::cout << "FIT PARAMETERS AFTER ROOMCSTUDY: lA: " << lA.getVal() << " lB: " << lB.getVal() << " lA1: " << lA1.getVal() << " lB1: " << lB1.getVal() << std::endl; std::cout << "===================================================================================================================================================" <<std::endl; //============================================================================================================================================= // Generate plots relevant to the toy fit //============================================================================================================================================= RooPlot* lFrame1 = lToy->plotPull(lNSig,-5,5,100,kTRUE); lFrame1->SetTitle("distribution of pulls on signal yield from toys"); lFrame1->SetXTitle("N_{sig} pull"); TCanvas* lC00 = new TCanvas("pulls","pulls",600,600) ; lC00->cd(); lFrame1->GetYaxis()->SetTitleOffset(1.2); lFrame1->GetXaxis()->SetTitleOffset(1.0); lFrame1->Draw() ; lC00->SaveAs(("sig_pulls_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); RooPlot* lFrame2 = lToy->plotParam(lA1); lFrame2->SetTitle("distribution of values of parameter 1 (a) after toy fit"); lFrame2->SetXTitle("Parameter 1 (a)"); TCanvas* lC01 = new TCanvas("valA","valA",600,600) ; lFrame2->Draw() ; lC01->SaveAs(("valA_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); RooPlot* lFrame3 = lToy->plotParam(lB1); lFrame3->SetTitle("distribution of values of parameter 2 (b) after toy fit"); lFrame3->SetXTitle("Parameter 2 (b)"); TCanvas* lC02 = new TCanvas("valB","valB",600,600) ; lFrame3->Draw() ; lC02->SaveAs(("valB_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); RooPlot* lFrame6 = lToy->plotNLL(0,1000,100); lFrame6->SetTitle("-log(L)"); lFrame6->SetXTitle("-log(L)"); TCanvas* lC05 = new TCanvas("logl","logl",600,600) ; lFrame6->Draw() ; lC05->SaveAs(("logL_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); RooPlot* lFrame7 = lToy->plotParam(lNSig); lFrame7->SetTitle("distribution of values of N_{sig} after toy fit"); lFrame7->SetXTitle("N_{sig}"); TCanvas* lC06 = new TCanvas("Nsig","Nsig",600,600) ; lFrame7->Draw() ; lC06->SaveAs(("NSig_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); RooPlot* lFrame8 = lToy->plotParam(lNB); lFrame8->SetTitle("distribution of values of N_{bkg} after toy fit"); lFrame8->SetXTitle("N_{bkg}"); TCanvas* lC07 = new TCanvas("Nbkg","Nbkg",600,600) ; lFrame8->Draw() ; lC07->SaveAs(("Nbkg_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str()); if(iRebin) { const int lNBins = lData->GetNbinsX(); double *lAxis = getAxis(lData); lH0 = rebin(lH0 ,lNBins,lAxis); lH = rebin(lH ,lNBins,lAxis); lHUp = rebin(lHUp ,lNBins,lAxis); lHDown = rebin(lHDown ,lNBins,lAxis); lHUp1 = rebin(lHUp1 ,lNBins,lAxis); lHDown1 = rebin(lHDown1,lNBins,lAxis); } // we dont need this bin errors since we do not use them (fit tails replaces bin-by-bin error!), therefore i set all errors to 0, this also saves us from modifying the add_bbb_error.py script in which I otherwise would have to include a option for adding bbb only in specific ranges int lMergeBin = lH->GetXaxis()->FindBin(iFirst); for(int i0 = lMergeBin; i0 < lH->GetNbinsX()+1; i0++){ lH->SetBinError (i0,0); lHUp->SetBinError (i0,0); lHDown->SetBinError (i0,0); lHUp1->SetBinError (i0,0); lHDown1->SetBinError (i0,0); } TFile *lOutFile =new TFile("Output.root","RECREATE"); cloneFile(lOutFile,lFile,iDir+"/"+iBkg); lOutFile->cd(iDir.c_str()); lH ->Write(); lHUp ->Write(); lHDown ->Write(); lHUp1 ->Write(); lHDown1->Write(); // Debug Plots lH0->SetStats(0); lH->SetStats(0); lHUp->SetStats(0); lHDown->SetStats(0); lHUp1->SetStats(0); lHDown1->SetStats(0); lH0 ->SetLineWidth(1); lH0->SetMarkerStyle(kFullCircle); lH ->SetLineColor(kGreen); lHUp ->SetLineColor(kRed); lHDown ->SetLineColor(kRed); lHUp1 ->SetLineColor(kBlue); lHDown1->SetLineColor(kBlue); TCanvas *lC0 = new TCanvas("Can","Can",800,600); lC0->Divide(1,2); lC0->cd(); lC0->cd(1)->SetPad(0,0.2,1.0,1.0); gPad->SetLeftMargin(0.2) ; lH0->Draw(); lH ->Draw("hist sames"); lHUp ->Draw("hist sames"); lHDown ->Draw("hist sames"); lHUp1 ->Draw("hist sames"); lHDown1->Draw("hist sames"); gPad->SetLogy(); TLegend* leg1; /// setup the CMS Preliminary leg1 = new TLegend(0.7, 0.80, 1, 1); leg1->SetBorderSize( 0 ); leg1->SetFillStyle ( 1001 ); leg1->SetFillColor (kWhite); leg1->AddEntry( lH0 , "orignal", "PL" ); leg1->AddEntry( lH , "cental fit", "L" ); leg1->AddEntry( lHUp , "shift1 up", "L" ); leg1->AddEntry( lHDown , "shift1 down", "L" ); leg1->AddEntry( lHUp1 , "shift2 up", "L" ); leg1->AddEntry( lHDown1 , "shift2 down", "L" ); leg1->Draw("same"); lC0->cd(2)->SetPad(0,0,1.0,0.2); gPad->SetLeftMargin(0.2) ; drawDifference(lH0,lH,lHUp,lHDown,lHUp1,lHDown1); lH0->SetStats(0); lC0->Update(); lC0->SaveAs((iBkg+"_"+"CMS_"+iName+"1_" + iDir + "_" + iEnergy+".png").c_str()); //lFile->Close(); return; }
void addNuisance(std::string iFileName,std::string iChannel,std::string iBkg,std::string iEnergy,std::string iName,std::string iDir,bool iRebin=true,bool iVarBin=false,int iFitModel=1,double iFirst=150,double iLast=1500) { std::cout << "======> " << iDir << "/" << iBkg << " -- " << iFileName << std::endl; if(iVarBin) addVarBinNuisance(iFileName,iChannel,iBkg,iEnergy,iName,iDir,iRebin,iFitModel,iFirst,iLast); if(iVarBin) return; TFile *lFile = new TFile(iFileName.c_str()); TH1F *lH0 = (TH1F*) lFile->Get((iDir+"/"+iBkg).c_str()); TH1F *lData = (TH1F*) lFile->Get((iDir+"/data_obs").c_str()); //Define the fit function RooRealVar lM("m","m" ,0,5000); //lM.setBinning(lBinning); RooRealVar lA("a","a" ,50, 0.1,100); RooRealVar lB("b","b" ,0.0 , -10.5,10.5); //lB.setConstant(kTRUE); RooDataHist *pH0 = new RooDataHist("Data","Data" ,RooArgList(lM),lH0); RooGenericPdf *lFit = 0; lFit = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB)); if(iFitModel == 1) lFit = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB)); if(iFitModel == 1) {lA.setVal(0.3); lB.setVal(0.5);} if(iFitModel == 2) lFit = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB)); if(iFitModel == 3) lFit = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB)); RooFitResult *lRFit = 0; double lFirst = iFirst; double lLast = iLast; //lRFit = lFit->chi2FitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast)); lRFit = lFit->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast),RooFit::Strategy(0)); TMatrixDSym lCovMatrix = lRFit->covarianceMatrix(); TMatrixD lEigVecs(2,2); lEigVecs = TMatrixDSymEigen(lCovMatrix).GetEigenVectors(); TVectorD lEigVals(2); lEigVals = TMatrixDSymEigen(lCovMatrix).GetEigenValues(); cout << " Ve---> " << lEigVecs(0,0) << " -- " << lEigVecs(1,0) << " -- " << lEigVecs(0,1) << " -- " << lEigVecs(1,1) << endl; cout << " Co---> " << lCovMatrix(0,0) << " -- " << lCovMatrix(1,0) << " -- " << lCovMatrix(0,1) << " -- " << lCovMatrix(1,1) << endl; double lACentral = lA.getVal(); double lBCentral = lB.getVal(); lEigVals(0) = sqrt(lEigVals(0)); lEigVals(1) = sqrt(lEigVals(1)); cout << "===> " << lEigVals(0) << " -- " << lEigVals(1) << endl; TH1F* lH = (TH1F*) lFit->createHistogram("fit" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral + lEigVals(0)*lEigVecs(0,0)); lB.setVal(lBCentral + lEigVals(0)*lEigVecs(1,0)); TH1F* lHUp = (TH1F*) lFit->createHistogram("Up" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral - lEigVals(0)*lEigVecs(0,0)); lB.setVal(lBCentral - lEigVals(0)*lEigVecs(1,0)); TH1F* lHDown = (TH1F*) lFit->createHistogram("Down",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral + lEigVals(1)*lEigVecs(0,1)); lB.setVal(lBCentral + lEigVals(1)*lEigVecs(1,1)); TH1F* lHUp1 = (TH1F*) lFit->createHistogram("Up1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); lA.setVal(lACentral - lEigVals(1)*lEigVecs(0,1)); lB.setVal(lBCentral - lEigVals(1)*lEigVecs(1,1)); TH1F* lHDown1 = (TH1F*) lFit->createHistogram("Down1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax())); std::string lNuisance1 = iBkg+"_"+"CMS_"+iName+"1_" + iChannel + "_" + iEnergy; std::string lNuisance2 = iBkg+"_"+"CMS_"+iName+"2_" + iChannel + "_" + iEnergy; lHUp = merge(lNuisance1 + "Up" ,lFirst,lH0,lHUp); lHDown = merge(lNuisance1 + "Down" ,lFirst,lH0,lHDown); lHUp1 = merge(lNuisance2 + "Up" ,lFirst,lH0,lHUp1); lHDown1 = merge(lNuisance2 + "Down" ,lFirst,lH0,lHDown1); lH = merge(lH0->GetName() ,lFirst,lH0,lH); if(iRebin) { const int lNBins = lData->GetNbinsX(); double *lAxis = getAxis(lData); lH0 = rebin(lH0 ,lNBins,lAxis); lH = rebin(lH ,lNBins,lAxis); lHUp = rebin(lHUp ,lNBins,lAxis); lHDown = rebin(lHDown ,lNBins,lAxis); lHUp1 = rebin(lHUp1 ,lNBins,lAxis); lHDown1 = rebin(lHDown1,lNBins,lAxis); } // we dont need this bin errors since we do not use them (fit tails replaces bin-by-bin error!), therefore i set all errors to 0, this also saves us from modifying the add_bbb_error.py script in which I otherwise would have to include a option for adding bbb only in specific ranges int lMergeBin = lH->GetXaxis()->FindBin(iFirst); for(int i0 = lMergeBin; i0 < lH->GetNbinsX()+1; i0++){ lH->SetBinError (i0,0); lHUp->SetBinError (i0,0); lHDown->SetBinError (i0,0); lHUp1->SetBinError (i0,0); lHDown1->SetBinError (i0,0); } TFile *lOutFile =new TFile("Output.root","RECREATE"); cloneFile(lOutFile,lFile,iDir+"/"+iBkg); lOutFile->cd(iDir.c_str()); lH ->Write(); lHUp ->Write(); lHDown ->Write(); lHUp1 ->Write(); lHDown1->Write(); // Debug Plots lH0->SetStats(0); lH->SetStats(0); lHUp->SetStats(0); lHDown->SetStats(0); lHUp1->SetStats(0); lHDown1->SetStats(0); lH0 ->SetLineWidth(1); lH0->SetMarkerStyle(kFullCircle); lH ->SetLineColor(kGreen); lHUp ->SetLineColor(kRed); lHDown ->SetLineColor(kRed); lHUp1 ->SetLineColor(kBlue); lHDown1->SetLineColor(kBlue); TCanvas *lC0 = new TCanvas("Can","Can",800,600); lC0->Divide(1,2); lC0->cd(); lC0->cd(1)->SetPad(0,0.2,1.0,1.0); gPad->SetLeftMargin(0.2) ; lH0->Draw(); lH ->Draw("hist sames"); lHUp ->Draw("hist sames"); lHDown ->Draw("hist sames"); lHUp1 ->Draw("hist sames"); lHDown1->Draw("hist sames"); gPad->SetLogy(); TLegend* leg1; /// setup the CMS Preliminary leg1 = new TLegend(0.7, 0.80, 1, 1); leg1->SetBorderSize( 0 ); leg1->SetFillStyle ( 1001 ); leg1->SetFillColor (kWhite); leg1->AddEntry( lH0 , "orignal", "PL" ); leg1->AddEntry( lH , "cental fit", "L" ); leg1->AddEntry( lHUp , "shift1 up", "L" ); leg1->AddEntry( lHDown , "shift1 down", "L" ); leg1->AddEntry( lHUp1 , "shift2 up", "L" ); leg1->AddEntry( lHDown1 , "shift2 down", "L" ); leg1->Draw("same"); lC0->cd(2)->SetPad(0,0,1.0,0.2); gPad->SetLeftMargin(0.2) ; drawDifference(lH0,lH,lHUp,lHDown,lHUp1,lHDown1); lH0->SetStats(0); lC0->Update(); lC0->SaveAs((iBkg+"_"+"CMS_"+iName+"1_" + iDir + "_" + iEnergy+".png").c_str()); //lFile->Close(); return; }
//I would recommend to use the other version of the fit code void addVarBinNuisance(std::string iFileName,std::string iChannel,std::string iBkg,std::string iEnergy,std::string iName,std::string iDir,bool iRebin=true,int iFitModel=0,double iFirst=200,double iLast=1500) { std::cout << "======> " << iDir << "/" << iBkg << " -- " << iFileName << std::endl; TFile *lFile = new TFile(iFileName.c_str()); TH1F *lH0 = (TH1F*) lFile->Get((iDir+"/"+iBkg).c_str()); TH1F *lData = (TH1F*) lFile->Get((iDir+"/data_obs").c_str()); for(int i0 = 0; i0 < lH0->GetNbinsX()+1; i0++) lH0->SetBinContent(i0,lH0->GetBinContent(i0)/lH0->GetXaxis()->GetBinWidth(i0)); for(int i0 = 0; i0 < lH0->GetNbinsX()+1; i0++) lH0->SetBinError (i0,lH0->GetBinError (i0)/lH0->GetXaxis()->GetBinWidth(i0)); //Define the fit function double lFirst = iFirst; double lLast = iLast; //TF1 *lFit = new TF1("Fit","[2]*exp(-x/([0]+[1]*x))",0,5000); TF1 *lFit = new TF1("expspec","[2]*exp(-x/([0]+[1]*x))",0,5000); if(iFitModel == 1) lFit = new TF1("expspec","[2]*exp(-[0]*pow(x,[1]))",0,5000); lFit->SetParLimits(2,0,10000000); lFit->SetParameter(2,lH0->Integral()); lFit->SetParLimits(0, 0,100); lFit->SetParameter(0,20); lFit->SetParLimits(1,-10,10); lFit->SetParameter(1,0); if(iFitModel == 1) lFit->SetParameter(0,0.3); if(iFitModel == 2) lFit->SetParameter(1,0.5); //TFitResultPtr lFitPtr = lH0->Fit("expspec","SEWL","IR",lFirst,lLast); TFitResultPtr lFitPtr = lH0->Fit("expspec","SER","R",lFirst,lLast); TMatrixDSym lCovMatrix = lFitPtr->GetCovarianceMatrix(); TMatrixD lEigVecs(3,3); lEigVecs = TMatrixDSymEigen(lCovMatrix).GetEigenVectors(); TVectorD lEigVals(3); lEigVals = TMatrixDSymEigen(lCovMatrix).GetEigenValues(); double lACentral = lFit->GetParameter(0); double lBCentral = lFit->GetParameter(1); lEigVals(0) = sqrt(lEigVals(1)); lEigVals(1) = sqrt(lEigVals(2)); for(int i0 = 0; i0 < lH0->GetNbinsX()+1; i0++) lH0->SetBinContent(i0,lH0->GetBinContent(i0)*lH0->GetXaxis()->GetBinWidth(i0)); for(int i0 = 0; i0 < lH0->GetNbinsX()+1; i0++) lH0->SetBinError (i0,lH0->GetBinError (i0)*lH0->GetXaxis()->GetBinWidth(i0)); lEigVecs(0,0) = lEigVecs(0,1); lEigVecs(1,0) = lEigVecs(1,1); lEigVecs(0,1) = lEigVecs(0,2); lEigVecs(1,1) = lEigVecs(1,2); TH1F* lH = makeHist(lFit,lH0,"Def"); lFit->SetParameter(0,lACentral + lEigVals(0)*lEigVecs(0,0)); lFit->SetParameter(1,lBCentral + lEigVals(0)*lEigVecs(1,0)); TH1F* lHUp = makeHist(lFit,lH0,"Up"); lFit->SetParameter(0,lACentral - lEigVals(0)*lEigVecs(0,0)); lFit->SetParameter(1,lBCentral - lEigVals(0)*lEigVecs(1,0)); TH1F* lHDown = makeHist(lFit,lH0,"Down"); lFit->SetParameter(0,lACentral + lEigVals(1)*lEigVecs(0,1)); lFit->SetParameter(1,lBCentral + lEigVals(1)*lEigVecs(1,1)); TH1F* lHUp1 = makeHist(lFit,lH0,"Up1"); lFit->SetParameter(0,lACentral - lEigVals(1)*lEigVecs(0,1)); lFit->SetParameter(1,lBCentral - lEigVals(1)*lEigVecs(1,1)); TH1F* lHDown1 = makeHist(lFit,lH0,"Down1"); //lFirst = 200; std::string lNuisance1 = iBkg+"_"+"CMS_"+iName+"1_" + iChannel + "_" + iEnergy; std::string lNuisance2 = iBkg+"_"+"CMS_"+iName+"2_" + iChannel + "_" + iEnergy; lHUp = merge(lNuisance1 + "Up" ,lFirst,lH0,lHUp); lHDown = merge(lNuisance1 + "Down" ,lFirst,lH0,lHDown); lHUp1 = merge(lNuisance2 + "Up" ,lFirst,lH0,lHUp1); lHDown1 = merge(lNuisance2 + "Down" ,lFirst,lH0,lHDown1); lH = merge(lH0->GetName() ,lFirst,lH0,lH); if(iRebin) { const int lNBins = lData->GetNbinsX(); double *lAxis = getAxis(lData); lH0 = rebin(lH0 ,lNBins,lAxis); lH = rebin(lH ,lNBins,lAxis); lHUp = rebin(lHUp ,lNBins,lAxis); lHDown = rebin(lHDown ,lNBins,lAxis); lHUp1 = rebin(lHUp1 ,lNBins,lAxis); lHDown1 = rebin(lHDown1,lNBins,lAxis); } TFile *lOutFile =new TFile("Output.root","RECREATE"); cloneFile(lOutFile,lFile,iDir+"/"+iBkg); lOutFile->cd(iDir.c_str()); lH ->Write(); lHUp ->Write(); lHDown ->Write(); lHUp1 ->Write(); lHDown1->Write(); // Debug Plots lH0 ->SetLineWidth(1); lH0->SetMarkerStyle(kFullCircle); lH ->SetLineColor(kGreen); lHUp ->SetLineColor(kRed); lHDown ->SetLineColor(kRed); lHUp1 ->SetLineColor(kBlue); lHDown1->SetLineColor(kBlue); TCanvas *lC0 = new TCanvas("Can","Can",800,600); lC0->Divide(1,2); lC0->cd(); lC0->cd(1)->SetPad(0,0.2,1.0,1.0); gPad->SetLeftMargin(0.2) ; lH0->Draw(); lH ->Draw("hist sames"); lHUp ->Draw("hist sames"); lHDown ->Draw("hist sames"); lHUp1 ->Draw("hist sames"); lHDown1->Draw("hist sames"); gPad->SetLogy(); lC0->cd(2)->SetPad(0,0,1.0,0.2); gPad->SetLeftMargin(0.2) ; drawDifference(lH0,lH,lHUp,lHDown,lHUp1,lHDown1); lC0->SaveAs((iBkg+"_"+"CMS_"+iName+"1_" + iDir + "_" + iEnergy+".png").c_str()); //lFile->Close(); return; }