//Created by KVClassFactory on Wed Sep 9 10:51:47 2015 //Author: fable #include "NewRooAddPdf.h" #include "NewRooGlobalFunc.h" #include "NewRooMinimizer.h" #include "NewRooMinuit.h" #include "NewRooFitResult.h" //#include "NewRooAddition.h" //#include "NewRooNLLVar.h" //#include "NewRooAbsReal.h" #include "RooFit.h" #include "RooMsgService.h" #include "TClass.h" #include "Riostream.h" #include "TMath.h" #include "TObjString.h" #include "TPaveText.h" #include "TList.h" #include "TH1.h" #include "TH2.h" #include "TMatrixD.h" #include "TMatrixDSym.h" #include "RooAbsPdf.h" #include "RooDataSet.h" #include "RooArgSet.h" #include "RooArgProxy.h" #include "RooRealProxy.h" #include "RooRealVar.h" #include "RooGenContext.h" #include "RooBinnedGenContext.h" #include "RooPlot.h" #include "RooCurve.h" #include "RooNLLVar.h" #include "RooCategory.h" #include "RooNameReg.h" #include "RooCmdConfig.h" #include "RooGlobalFunc.h" #include "RooAddition.h" #include "RooRandom.h" #include "RooNumIntConfig.h" #include "RooProjectedPdf.h" #include "RooInt.h" #include "RooCustomizer.h" #include "RooConstraintSum.h" #include "RooParamBinning.h" #include "RooNumCdf.h" #include "RooFitResult.h" #include "RooNumGenConfig.h" #include "RooCachedReal.h" #include "RooXYChi2Var.h" #include "RooChi2Var.h" #include "RooRealIntegral.h" #include "Math/CholeskyDecomp.h" #include "RooRecursiveFraction.h" #include "RooArgList.h" #include "TNamed.h" #include "RooConstVar.h" #include "RooAddPdf.h" using namespace RooFit; ClassImp(NewRooAddPdf) //////////////////////////////////////////////////////////////////////////////// // BEGIN_HTML

NewRooAddPdf

Modified RooFit class NewRooAddPdf with new fit options

END_HTML //////////////////////////////////////////////////////////////////////////////// //Modified //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf() : RooAddPdf() { // Default constructor used for persistence fnll=0; finit_nll=0; } //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf(const char *name, const char *title) : RooAddPdf(name, title) { // Dummy constructor delete fnll ; delete finit_nll ; } //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf(const char *name, const char *title, RooAbsPdf& pdf1, RooAbsPdf& pdf2, RooAbsReal& coef1) : RooAddPdf(name, title, pdf1, pdf2, coef1) { // Constructor with two PDFs and one coefficient } //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf(const char *name, const char *title, const RooArgList& inPdfList, const RooArgList& inCoefList, Bool_t recursiveFractions) : RooAddPdf(name, title, inPdfList, inCoefList, recursiveFractions) { // Generic constructor from list of PDFs and list of coefficients. // Each pdf list element (i) is paired with coefficient list element (i). // The number of coefficients must be either equal to the number of PDFs, // in which case extended MLL fitting is enabled, or be one less. // // All PDFs must inherit from RooAbsPdf. All coefficients must inherit from RooAbsReal // // If the recursiveFraction flag is true, the coefficients are interpreted as recursive // coefficients as explained in the class description. _refCoefNorm = RooSetProxy("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE); _refCoefRangeName = 0; _projectCoefs = kFALSE; _projCacheMgr = RooObjCacheManager(this,10); _codeReg = 10; _pdfList = RooListProxy("!pdfs","List of PDFs",this), _coefList = RooListProxy("!coefficients","List of coefficients",this), _haveLastCoef = kFALSE; _allExtendable = kFALSE; _recursive = kFALSE; if (inPdfList.getSize()>inCoefList.getSize()+1 || inPdfList.getSize()Next())) { pdf = (RooAbsPdf*) pdfIter->Next() ; if (!pdf) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ; assert(0) ; } if (!dynamic_cast(coef)) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") coefficient " << coef->GetName() << " is not of type RooAbsReal, ignored" << endl ; continue ; } if (!dynamic_cast(pdf)) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ; continue ; } _pdfList.add(*pdf) ; // Process recursive fraction mode separately if (recursiveFractions) { partinCoefList.add(*coef) ; if (first) { // The first fraction is the first plain fraction first = kFALSE ; _coefList.add(*coef) ; } else { // The i-th recursive fraction = (1-f1)*(1-f2)*...(fi) and is calculated from the list (f1,...,fi) by RooRecursiveFraction) RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ; NewRooAddPdf::addOwnedComponents(*rfrac, kTRUE) ; _coefList.add(*rfrac, kTRUE) ; } } else { _coefList.add(*coef) ; } } pdf = (RooAbsPdf*) pdfIter->Next() ; if (pdf) { if (!dynamic_cast(pdf)) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") last pdf " << coef->GetName() << " is not of type RooAbsPdf, fatal error" << endl ; assert(0) ; } _pdfList.add(*pdf) ; // Process recursive fractions mode if (recursiveFractions) { // The last recursive fraction = (1-f1)*(1-f2)*...(1-fN) and is calculated from the list (f1,...,fN,1) by RooRecursiveFraction) partinCoefList.add(RooFit::RooConst(1)) ; RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ; NewRooAddPdf::addOwnedComponents(*rfrac, kTRUE) ; _coefList.add(*rfrac, kTRUE) ; // In recursive mode we always have Ncoef=Npdf _haveLastCoef=kTRUE ; } } else { _haveLastCoef=kTRUE ; } delete pdfIter ; delete coefIter ; _coefCache = new Double_t[_pdfList.getSize()] ; _coefErrCount = _errorCount ; _recursive = recursiveFractions ; TRACE_CREATE } //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf(const char *name, const char *title, const RooArgList& inPdfList) : RooAddPdf(name, title, inPdfList) { // Generic constructor from list of extended PDFs. There are no coefficients as the expected // number of events from each components determine the relative weight of the PDFs. // // All PDFs must inherit from RooAbsPdf. _refCoefNorm = RooSetProxy("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE), _refCoefRangeName = 0; _projectCoefs = kFALSE; _projCacheMgr = RooObjCacheManager(this,10); _pdfList = RooListProxy("!pdfs","List of PDFs",this); _coefList = RooListProxy("!coefficients","List of coefficients",this); _haveLastCoef = kFALSE; _allExtendable = kTRUE; _recursive = kFALSE; _pdfIter = _pdfList.createIterator() ; _coefIter = _coefList.createIterator() ; // Constructor with N PDFs TIterator* pdfIter = inPdfList.createIterator() ; RooAbsPdf* pdf ; while((pdf = (RooAbsPdf*) pdfIter->Next())) { if (!dynamic_cast(pdf)) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ; continue ; } if (!pdf->canBeExtended()) { coutE(InputArguments) << "NewRooAddPdf::NewRooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not extendable, ignored" << endl ; continue ; } _pdfList.add(*pdf) ; } delete pdfIter ; _coefCache = new Double_t[_pdfList.getSize()] ; _coefErrCount = _errorCount ; TRACE_CREATE } //_____________________________________________________________________________ NewRooAddPdf::NewRooAddPdf(const NewRooAddPdf& other, const char* name) : RooAddPdf(other, name) { // Copy constructor } //_____________________________________________________________________________ NewRooAddPdf::~NewRooAddPdf() { // Destructor } //////////////////////////////////////////////////////////////////////////////// RooFitResult* NewRooAddPdf::improvedFitTo(RooDataHist& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8, const RooCmdArg& arg9, const RooCmdArg& arg10, const RooCmdArg& arg11, const RooCmdArg& arg12) { //RooLinkedList creation RooLinkedList l ; l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ; l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ; l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ; l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ; l.Add((TObject*)&arg9) ; l.Add((TObject*)&arg10); l.Add((TObject*)&arg11); l.Add((TObject*)&arg12); return improvedFitTo(data, l); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RooFitResult* NewRooAddPdf::improvedFitTo(RooDataHist& data, const RooLinkedList& cmdList) { // Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset // is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT // commands MIGRAD, HESSE and MINOS in succession. // // Some new commands: SetMaxIter(Int_t), SetMaxCalls(Int_t) and SetEpsilon(Double_t) // New commands added in a new "NewRooGlobalFunc" for covenience // // See RooAbsPdf::improvedFitTo(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4, // RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8) // // for documentation of options // Select the pdf-specific commands RooCmdConfig pc(Form("RooAbsPdf::improvedFitTo(%s)",GetName())) ; RooLinkedList fitCmdList(cmdList) ; // Add options here RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,CloneData,GlobalObservables,GlobalObservablesTag,OffsetLikelihood") ; pc.defineString("fitOpt","FitOptions",0,"") ; pc.defineInt("optConst","Optimize",0,2) ; pc.defineInt("verbose","Verbose",0,0) ; pc.defineInt("doSave","Save",0,0) ; pc.defineInt("doTimer","Timer",0,0) ; pc.defineInt("plevel","PrintLevel",0,1) ; pc.defineInt("strat","Strategy",0,1) ; pc.defineInt("initHesse","InitialHesse",0,0) ; pc.defineInt("hesse","Hesse",0,1) ; pc.defineInt("minos","Minos",0,0) ; pc.defineInt("ext","Extended",0,2) ; pc.defineInt("numcpu","NumCPU",0,1) ; pc.defineInt("numee","PrintEvalErrors",0,10) ; pc.defineInt("doEEWall","EvalErrorWall",0,1) ; pc.defineInt("doWarn","Warnings",0,1) ; pc.defineInt("doSumW2","SumW2Error",0,-1) ; pc.defineInt("doOffset","OffsetLikelihood",0,0) ; pc.defineString("mintype","Minimizer",0,"OldMinuit") ; pc.defineString("minalg","Minimizer",1,"minuit") ; pc.defineObject("minosSet","Minos",0,0) ; pc.defineSet("cPars","Constrain",0,0) ; pc.defineSet("extCons","ExternalConstraints",0,0) ; pc.defineMutex("FitOptions","Verbose") ; pc.defineMutex("FitOptions","Save") ; pc.defineMutex("FitOptions","Timer") ; pc.defineMutex("FitOptions","Strategy") ; pc.defineMutex("FitOptions","InitialHesse") ; pc.defineMutex("FitOptions","Hesse") ; pc.defineMutex("FitOptions","Minos") ; pc.defineMutex("Range","RangeWithName") ; pc.defineMutex("InitialHesse","Minimizer") ; // New Commands pc.defineInt("numiter", "SetMaxIter", 0, 0); //Modify number of max iteration pc.defineInt("numcalls","SetMaxCalls", 0, 0); //Modify number of max calls pc.defineDouble("eps", "SetEpsilon", 0, 1.0); //Modify tolerance value of the fit (convergence) // Process and check varargs pc.process(fitCmdList) ; if (!pc.ok(kTRUE)) { return 0 ; } // Decode command line arguments const char* fitOpt = pc.getString("fitOpt",0,kTRUE) ; Int_t optConst = pc.getInt("optConst") ; Int_t verbose = pc.getInt("verbose") ; Int_t doSave = pc.getInt("doSave") ; Int_t doTimer = pc.getInt("doTimer") ; Int_t plevel = pc.getInt("plevel") ; Int_t strat = pc.getInt("strat") ; Int_t initHesse= pc.getInt("initHesse") ; Int_t hesse = pc.getInt("hesse") ; Int_t minos = pc.getInt("minos") ; Int_t numee = pc.getInt("numee") ; Int_t doEEWall = pc.getInt("doEEWall") ; Int_t doWarn = pc.getInt("doWarn") ; Int_t doSumW2 = pc.getInt("doSumW2") ; Int_t numiter = pc.getInt("numiter") ; Int_t numcalls = pc.getInt("numcalls") ; Double_t eps = pc.getDouble("eps"); const RooArgSet* minosSet = static_cast(pc.getObject("minosSet")) ; #ifdef __ROOFIT_NOROOMINIMIZER const char* minType =0 ; #else const char* minType = pc.getString("mintype","OldMinuit") ; const char* minAlg = pc.getString("minalg","minuit") ; #endif // Determine if the dataset has weights Bool_t weightedData = data.isNonPoissonWeighted() ; // Warn user that a SumW2Error() argument should be provided if weighted data is offered if (weightedData && doSumW2==-1) { coutW(InputArguments) << "RooAbsPdf::improvedFitTo(" << GetName() << ") WARNING: a likelihood fit is request of what appears to be weighted data. " << endl << " While the estimated values of the parameters will always be calculated taking the weights into account, " << endl << " there are multiple ways to estimate the errors on these parameter values. You are advised to make an " << endl << " explicit choice on the error calculation: " << endl << " - Either provide SumW2Error(kTRUE), to calculate a sum-of-weights corrected HESSE error matrix " << endl << " (error will be proportional to the number of events)" << endl << " - Or provide SumW2Error(kFALSE), to return errors from original HESSE error matrix" << endl << " (which will be proportional to the sum of the weights)" << endl << " If you want the errors to reflect the information contained in the provided dataset, choose kTRUE. " << endl << " If you want the errors to reflect the precision you would be able to obtain with an unweighted dataset " << endl << " with 'sum-of-weights' events, choose kFALSE." << endl ; } // Warn user that sum-of-weights correction does not apply to MINOS errrors if (doSumW2==1 && minos) { coutW(InputArguments) << "RooAbsPdf::improvedFitTo(" << GetName() << ") WARNING: sum-of-weights correction does not apply to MINOS errors" << endl ; } finit_nll = createNLL(data, nllCmdList); fnll = createNLL(data, nllCmdList); //fnll = new RooAbsReal(*finit_nll); NewRooFitResult *ret = 0 ; // Instantiate MINUIT if (string(minType)!="OldMinuit") { #ifndef __ROOFIT_NOROOMINIMIZER //debug //printf("USING NEWROOMINIMIZER\n"); NewRooMinimizer m(*fnll) ; m.setMinimizerType(minType) ; m.setEvalErrorWall(doEEWall) ; if (doWarn==0) { // m.setNoWarn() ; WVE FIX THIS } //New commands if(numiter>0) m.setMaxIterations(numiter); if(numcalls>0) m.setMaxFunctionCalls(numcalls); m.setEps(eps); m.setPrintEvalErrors(numee) ; if (plevel!=1) { m.setPrintLevel(plevel) ; } if (optConst) { // Activate constant term optimization m.optimizeConst(optConst) ; } if (fitOpt) { // Play fit options as historically defined ret = m.fit(fitOpt) ; } else { if (verbose) { // Activate verbose options m.setVerbose(1) ; } if (doTimer) { // Activate timer options m.setProfile(1) ; } if (strat!=1) { // Modify fit strategy m.setStrategy(strat) ; } if (initHesse) { // Initialize errors with hesse m.hesse() ; } // Minimize using chosen algorithm m.minimize(minType,minAlg) ; if (hesse) { // Evaluate errors with Hesse m.hesse() ; } if (doSumW2==1 && m.getNPar()>0) { // Make list of RooNLLVar components of FCN RooArgSet* comps = fnll->getComponents(); vector nllComponents; nllComponents.reserve(comps->getSize()); TIterator* citer = comps->createIterator(); RooAbsArg* arg; while ((arg=(RooAbsArg*)citer->Next())) { RooNLLVar* nllComp = dynamic_cast(arg); if (!nllComp) continue; nllComponents.push_back(nllComp); } delete citer; delete comps; // Calculated corrected errors for weighted likelihood fits NewRooFitResult* rw = m.save(); for (vector::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) { (*it)->applyWeightSquared(kTRUE); } coutI(Fitting) << "RooAbsPdf::improvedFitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ; m.hesse(); NewRooFitResult* rw2 = m.save(); for (vector::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) { (*it)->applyWeightSquared(kFALSE); } // Apply correction matrix const TMatrixDSym& matV = rw->covarianceMatrix(); TMatrixDSym matC = rw2->covarianceMatrix(); using ROOT::Math::CholeskyDecompGenDim; CholeskyDecompGenDim decomp(matC.GetNrows(), matC); if (!decomp) { coutE(Fitting) << "RooAbsPdf::improvedFitTo(" << GetName() << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <0) { // Make list of RooNLLVar components of FCN list nllComponents ; RooArgSet* comps = fnll->getComponents() ; RooAbsArg* arg ; TIterator* citer = comps->createIterator() ; while((arg=(RooAbsArg*)citer->Next())) { RooNLLVar* nllComp = dynamic_cast(arg) ; if (nllComp) { nllComponents.push_back(nllComp) ; } } delete citer ; delete comps ; // Calculated corrected errors for weighted likelihood fits NewRooFitResult* rw = m.save() ; for (list::iterator iter1=nllComponents.begin() ; iter1!=nllComponents.end() ; iter1++) { (*iter1)->applyWeightSquared(kTRUE) ; } coutI(Fitting) << "RooAbsPdf::improvedFitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ; m.hesse() ; NewRooFitResult* rw2 = m.save() ; for (list::iterator iter2=nllComponents.begin() ; iter2!=nllComponents.end() ; iter2++) { (*iter2)->applyWeightSquared(kFALSE) ; } // Apply correction matrix const TMatrixDSym& matV = rw->covarianceMatrix(); TMatrixDSym matC = rw2->covarianceMatrix(); using ROOT::Math::CholeskyDecompGenDim; CholeskyDecompGenDim decomp(matC.GetNrows(), matC); if (!decomp) { coutE(Fitting) << "RooAbsPdf::improvedFitTo(" << GetName() << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <addOwned(comps, silent) ; } //_____________________________________________________________________________ RooAbsReal* NewRooAddPdf::createNLL(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) { // Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset // is binned, a binned likelihood is constructed. // // The following named arguments are supported // // ConditionalObservables(const RooArgSet& set) -- Do not normalize PDF over listed observables // Extended(Bool_t flag) -- Add extended likelihood term, off by default // Range(const char* name) -- Fit only data inside range with given name // Range(Double_t lo, Double_t hi) -- Fit only data inside given range. A range named "fit" is created on the fly on all observables. // Multiple comma separated range names can be specified. // SumCoefRange(const char* name) -- Set the range in which to interpret the coefficients of RooAddPdf components // NumCPU(int num, int strat) -- Parallelize NLL calculation on num CPUs // // Strategy 0 = RooFit::BulkPartition (Default) --> Divide events in N equal chunks // Strategy 1 = RooFit::Interleave --> Process event i%N in process N. Recommended for binned data with // a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy // Strategy 2 = RooFit::SimComponents --> Process each component likelihood of a RooSimultaneous fully in a single process // and distribute components over processes. This approach can be benificial if normalization calculation time // dominates the total computation time of a component (since the normalization calculation must be performed // in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many // parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing // a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components // do not share many parameters // Strategy 3 = RooFit::Hybrid --> Follow strategy 0 for all RooSimultaneous components, except those with less than // 30 dataset entries, for which strategy 2 is followed. // // Optimize(Bool_t flag) -- Activate constant term optimization (on by default) // SplitRange(Bool_t flag) -- Use separate fit ranges in a simultaneous fit. Actual range name for each // subsample is assumed to by rangeName_{indexState} where indexState // is the state of the master index category of the simultaneous fit // Constrain(const RooArgSet&pars) -- For p.d.f.s that contain internal parameter constraint terms, only apply constraints to given subset of parameters // ExternalConstraints(const RooArgSet& ) -- Include given external constraints to likelihood // GlobalObservables(const RooArgSet&) -- Define the set of normalization observables to be used for the constraint terms. // If none are specified the constrained parameters are used // GlobalObservablesTag(const char* tagName) -- Define the set of normalization observables to be used for the constraint terms by a string attribute // associated with pdf observables that match the given tagName // Verbose(Bool_t flag) -- Constrols RooFit informational messages in likelihood construction // CloneData(Bool flag) -- Use clone of dataset in NLL (default is true) // Offset(Bool_t) -- Offset likelihood by initial value (so that starting value of FCN in minuit is zero). This // can improve numeric stability in simultaneously fits with components with large likelihood values // // RooLinkedList l ; l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ; l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ; l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ; l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ; return createNLL(data,l) ; } //_____________________________________________________________________________ RooAbsReal* NewRooAddPdf::createNLL(RooAbsData& data, const RooLinkedList& cmdList) { // Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset // is binned, a binned likelihood is constructed. // // See RooAbsPdf::createNLL(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4, // RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8) // // for documentation of options // Select the pdf-specific commands RooCmdConfig pc(Form("NewRooAddPdf::createNLL(%s)",GetName())) ; pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ; pc.defineString("addCoefRange","SumCoefRange",0,"") ; pc.defineString("globstag","GlobalObservablesTag",0,"") ; pc.defineDouble("rangeLo","Range",0,-999.) ; pc.defineDouble("rangeHi","Range",1,-999.) ; pc.defineInt("splitRange","SplitRange",0,0) ; pc.defineInt("ext","Extended",0,2) ; pc.defineInt("numcpu","NumCPU",0,1) ; pc.defineInt("interleave","NumCPU",1,0) ; pc.defineInt("verbose","Verbose",0,0) ; pc.defineInt("optConst","Optimize",0,0) ; pc.defineInt("cloneData","CloneData",2,0) ; pc.defineSet("projDepSet","ProjectedObservables",0,0) ; pc.defineSet("cPars","Constrain",0,0) ; pc.defineSet("glObs","GlobalObservables",0,0) ; pc.defineInt("constrAll","Constrained",0,0) ; pc.defineInt("doOffset","OffsetLikelihood",0,0) ; pc.defineSet("extCons","ExternalConstraints",0,0) ; pc.defineMutex("Range","RangeWithName") ; pc.defineMutex("Constrain","Constrained") ; pc.defineMutex("GlobalObservables","GlobalObservablesTag") ; // Process and check varargs pc.process(cmdList) ; if (!pc.ok(kTRUE)) { return 0 ; } // Decode command line arguments const char* rangeName = pc.getString("rangeName",0,kTRUE) ; const char* addCoefRangeName = pc.getString("addCoefRange",0,kTRUE) ; const char* globsTag = pc.getString("globstag",0,kTRUE) ; Int_t ext = pc.getInt("ext") ; Int_t numcpu = pc.getInt("numcpu") ; RooFit::MPSplit interl = (RooFit::MPSplit) pc.getInt("interleave") ; Int_t splitr = pc.getInt("splitRange") ; Bool_t verbose = pc.getInt("verbose") ; Int_t optConst = pc.getInt("optConst") ; Int_t cloneData = pc.getInt("cloneData") ; Int_t doOffset = pc.getInt("doOffset") ; // If no explicit cloneData command is specified, cloneData is set to true if optimization is activated if (cloneData==2) { cloneData = optConst ; } RooArgSet* cPars = pc.getSet("cPars") ; RooArgSet* glObs = pc.getSet("glObs") ; if (pc.hasProcessed("GlobalObservablesTag")) { if (glObs) delete glObs ; RooArgSet* allVars = getVariables() ; glObs = (RooArgSet*) allVars->selectByAttrib(globsTag,kTRUE) ; coutI(Minimization) << "User-defined specification of global observables definition with tag named '" << globsTag << "'" << endl ; delete allVars ; } else if (!pc.hasProcessed("GlobalObservables")) { // Neither GlobalObservables nor GlobalObservablesTag has been processed - try if a default tag is defined in the head node // Check if head not specifies default global observable tag const char* defGlobObsTag = getStringAttribute("DefaultGlobalObservablesTag") ; if (defGlobObsTag) { coutI(Minimization) << "p.d.f. provides built-in specification of global observables definition with tag named '" << defGlobObsTag << "'" << endl ; if (glObs) delete glObs ; RooArgSet* allVars = getVariables() ; glObs = (RooArgSet*) allVars->selectByAttrib(defGlobObsTag,kTRUE) ; } } Bool_t doStripDisconnected=kFALSE ; // If no explicit list of parameters to be constrained is specified apply default algorithm // All terms of RooProdPdfs that do not contain observables and share a parameters with one or more // terms that do contain observables are added as constraints. if (!cPars) { cPars = getParameters(data,kFALSE) ; doStripDisconnected=kTRUE ; } const RooArgSet* extCons = pc.getSet("extCons") ; // Process automatic extended option if (ext==2) { ext = ((extendMode()==CanBeExtended || extendMode()==MustBeExtended)) ? 1 : 0 ; if (ext) { coutI(Minimization) << "p.d.f. provides expected number of events, including extended term in likelihood." << endl ; } } if (pc.hasProcessed("Range")) { Double_t rangeLo = pc.getDouble("rangeLo") ; Double_t rangeHi = pc.getDouble("rangeHi") ; // Create range with name 'fit' with above limits on all observables RooArgSet* obs = getObservables(&data) ; TIterator* iter = obs->createIterator() ; RooAbsArg* arg ; while((arg=(RooAbsArg*)iter->Next())) { RooRealVar* rrv = dynamic_cast(arg) ; if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ; } // Set range name to be fitted to "fit" rangeName = "fit" ; } RooArgSet projDeps ; RooArgSet* tmp = pc.getSet("projDepSet") ; if (tmp) { projDeps.add(*tmp) ; } // Construct NLL RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ; RooAbsReal* nll ; string baseName = Form("nll_%s_%s",GetName(),data.GetName()) ; if (!rangeName || strchr(rangeName,',')==0) { // Simple case: default range, or single restricted range //cout<<"FK: Data test 1: "<getSize()>0) { RooArgSet* constraints = getAllConstraints(*data.get(),*cPars,doStripDisconnected) ; allConstraints.add(*constraints, kTRUE) ; delete constraints ; } if (extCons) { allConstraints.add(*extCons, kTRUE) ; } // Include constraints, if any, in likelihood RooAbsReal* nllCons(0) ; if (allConstraints.getSize()>0 && cPars) { coutI(Minimization) << " Including the following contraint terms in minimization: " << allConstraints << endl ; if (glObs) { coutI(Minimization) << "The following global observables have been defined: " << *glObs << endl ; } nllCons = new RooConstraintSum(Form("%s_constr",baseName.c_str()),"nllCons",allConstraints,glObs ? *glObs : *cPars) ; nllCons->setOperMode(ADirty) ; RooAbsReal* orignll = nll ; nll = new RooAddition(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*nll,*nllCons)) ; nll->addOwnedComponents(RooArgSet(*orignll,*nllCons)) ; } //debug //printf("LAST OPERATION CREATE NLL\n"); if (optConst) { nll->constOptimizeTestStatistic(RooAbsArg::Activate,optConst>1) ; } if (doStripDisconnected) { delete cPars ; } if (doOffset) { //nll->enableSilentOffsetting(kTRUE) ; //Modified for no checkForDup() messages } return nll ; }