// A set of utils for navegating HistFactory models #include #include #include "RooStats/HistFactory/ParamHistFunc.h" #include "TIterator.h" #include "RooAbsArg.h" #include "RooAbsPdf.h" #include "RooArgSet.h" #include "RooArgList.h" #include "RooSimultaneous.h" #include "RooCategory.h" #include "RooRealVar.h" #include "RooProdPdf.h" #include "TH1.h" #include "RooStats/HistFactory/HistFactorySimultaneous.h" #include "RooStats/HistFactory/HistFactoryModelUtils.h" namespace RooStats{ namespace HistFactory{ std::string channelNameFromPdf( RooAbsPdf* channelPdf ) { std::string channelPdfName = channelPdf->GetName(); std::string ChannelName = channelPdfName.substr(6, channelPdfName.size() ); return ChannelName; } RooAbsPdf* getSumPdfFromChannel( RooAbsPdf* sim_channel ) { bool verbose=false; if(verbose) std::cout << "Getting the RooRealSumPdf for the channel: " << sim_channel->GetName() << std::endl; std::string channelPdfName = sim_channel->GetName(); std::string ChannelName = channelPdfName.substr(6, channelPdfName.size() ); // Now, get the RooRealSumPdf // ie the channel WITHOUT constraints std::string realSumPdfName = ChannelName + "_model"; RooAbsPdf* sum_pdf = NULL; TIterator* iter_sum_pdf = sim_channel->getComponents()->createIterator(); //serverIterator(); bool FoundSumPdf=false; RooAbsArg* sum_pdf_arg=NULL; while((sum_pdf_arg=(RooAbsArg*)iter_sum_pdf->Next())) { std::string NodeClassName = sum_pdf_arg->ClassName(); if( NodeClassName == std::string("RooRealSumPdf") ) { FoundSumPdf=true; sum_pdf = (RooAbsPdf*) sum_pdf_arg; break; } } if( ! FoundSumPdf ) { if(verbose) { std::cout << "Failed to find RooRealSumPdf for channel: " << sim_channel->GetName() << std::endl; sim_channel->getComponents()->Print("V"); } sum_pdf=NULL; //throw std::runtime_error("Failed to find RooRealSumPdf for channel"); } else { if(verbose) std::cout << "Found RooRealSumPdf: " << sum_pdf->GetName() << std::endl; } delete iter_sum_pdf; iter_sum_pdf = NULL; return sum_pdf; } void FactorizeHistFactoryPdf(const RooArgSet &observables, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints) { // utility function to factorize constraint terms from a pdf // (from G. Petrucciani) const std::type_info & id = typeid(pdf); if (id == typeid(RooProdPdf)) { RooProdPdf *prod = dynamic_cast(&pdf); RooArgList list(prod->pdfList()); for (int i = 0, n = list.getSize(); i < n; ++i) { RooAbsPdf *pdfi = (RooAbsPdf *) list.at(i); FactorizeHistFactoryPdf(observables, *pdfi, obsTerms, constraints); } } else if (id == typeid(RooSimultaneous) || id == typeid(HistFactorySimultaneous) ) { //|| id == typeid(RooSimultaneousOpt)) { RooSimultaneous *sim = dynamic_cast(&pdf); RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone(); for (int ic = 0, nc = cat->numBins((const char *)0); ic < nc; ++ic) { cat->setBin(ic); FactorizeHistFactoryPdf(observables, *sim->getPdf(cat->getLabel()), obsTerms, constraints); } delete cat; } else if (pdf.dependsOn(observables)) { if (!obsTerms.contains(pdf)) obsTerms.add(pdf); } else { if (!constraints.contains(pdf)) constraints.add(pdf); } } /* void getChannelsFromModel( RooAbsPdf* model, RooArgSet* channels, RooArgSet* channelsWithConstraints ) { // Loop through the model // Find all channels std::string modelClassName = model->ClassName(); if( modelClassName == std::string("RooSimultaneous") || model->InheritsFrom("RooSimultaneous") ) { TIterator* simServerItr = model->serverIterator(); // Loop through the child nodes of the sim pdf // and find the channel nodes RooAbsArg* sim_channel_arg = NULL; while(( sim_channel = (RooAbsArg*) simServerItr->Next() )) { RooAbsPdf* sim_channel = (RooAbsPdf*) sim_channel_arg; // Ignore the Channel Cat std::string channelPdfName = sim_channel->GetName(); std::string channelClassName = sim_channel->ClassName(); if( channelClassName == std::string("RooCategory") ) continue; // If we got here, we found a channel. // Format is model_ std::string ChannelName = channelPdfName.substr(6, channelPdfName.size() ); // Now, get the RooRealSumPdf RooAbsPdf* sum_pdf = getSumPdfFromChannel( sim_channel ); / * // Now, get the RooRealSumPdf // ie the channel WITHOUT constraints std::string realSumPdfName = ChannelName + "_model"; RooAbsPdf* sum_pdf = NULL; TIterator* iter_sum_pdf = sim_channel->getComponents()->createIterator(); //serverIterator(); bool FoundSumPdf=false; RooAbsArg* sum_pdf_arg=NULL; while((sum_pdf_arg=(RooAbsArg*)iter_sum_pdf->Next())) { std::string NodeClassName = sum_pdf_arg->ClassName(); if( NodeClassName == std::string("RooRealSumPdf") ) { FoundSumPdf=true; sum_pdf = (RooAbsPdf*) sum_pdf_arg; break; } } if( ! FoundSumPdf ) { std::cout << "Failed to find RooRealSumPdf for channel: " << sim_channel->GetName() << std::endl; sim_channel->getComponents()->Print("V"); throw std::runtime_error("Failed to find RooRealSumPdf for channel"); } delete iter_sum_pdf; iter_sum_pdf = NULL; * / // Okay, now add to the arg sets channels->add( *sum_pdf ); channelsWithConstraints->add( *sim_channel ); } delete simServerItr; } else { std::cout << "Model is not a RooSimultaneous or doesn't derive from one." << std::endl; std::cout << "HistFactoryModelUtils isn't yet implemented for these pdf's" << std::endl; } } */ bool getStatUncertaintyFromChannel( RooAbsPdf* channel, ParamHistFunc*& paramfunc, RooArgList* gammaList ) { bool verbose=false; // Find the servers of this channel //TIterator* iter = channel->serverIterator(); TIterator* iter = channel->getComponents()->createIterator(); //serverIterator(); bool FoundParamHistFunc=false; RooAbsArg* paramfunc_arg = NULL; while(( paramfunc_arg = (RooAbsArg*) iter->Next() )) { std::string NodeName = paramfunc_arg->GetName(); std::string NodeClassName = paramfunc_arg->ClassName(); if( NodeClassName != std::string("ParamHistFunc") ) continue; if( NodeName.find("mc_stat_") != std::string::npos ) { FoundParamHistFunc=true; paramfunc = (ParamHistFunc*) paramfunc_arg; break; } } if( ! FoundParamHistFunc || !paramfunc ) { if(verbose) std::cout << "Failed to find ParamHistFunc for channel: " << channel->GetName() << std::endl; return false; } delete iter; iter = NULL; // Now, get the set of gamma's gammaList = (RooArgList*) &( paramfunc->paramList()); if(verbose) gammaList->Print("V"); return true; } void getDataValuesForObservables( std::map< std::string, std::vector >& ChannelBinDataMap, RooAbsData* data, RooAbsPdf* pdf ) { bool verbose=false; //std::map< std::string, std::vector ChannelBinDataMap; RooSimultaneous* simPdf = (RooSimultaneous*) pdf; // get category label RooArgSet* allobs = (RooArgSet*) data->get(); TIterator* obsIter = allobs->createIterator(); RooCategory* cat = NULL; RooAbsArg* temp = NULL; while( (temp=(RooAbsArg*) obsIter->Next())) { // use dynamic cast here instead if( strcmp(temp->ClassName(),"RooCategory")==0){ cat = (RooCategory*) temp; break; } } if(verbose) { if(!cat) std::cout <<"didn't find category"<< std::endl; else std::cout <<"found category"<< std::endl; } delete obsIter; // split dataset TList* dataByCategory = data->split(*cat); if(verbose) dataByCategory->Print(); // note : // RooAbsData* dataForChan = (RooAbsData*) dataByCategory->FindObject(""); // loop over channels RooCategory* channelCat = (RooCategory*) (&simPdf->indexCat()); TIterator* iter = channelCat->typeIterator() ; RooCatType* tt = NULL; while((tt=(RooCatType*) iter->Next())) { // Get pdf associated with state from simpdf RooAbsPdf* pdftmp = simPdf->getPdf(tt->GetName()) ; std::string ChannelName = pdftmp->GetName(); //tt->GetName(); if(verbose) std::cout << "Getting data for channel: " << ChannelName << std::endl; ChannelBinDataMap[ ChannelName ] = std::vector(); RooAbsData* dataForChan = (RooAbsData*) dataByCategory->FindObject(tt->GetName()); if(verbose) dataForChan->Print(); // Generate observables defined by the pdf associated with this state RooArgSet* obstmp = pdftmp->getObservables(*dataForChan->get()) ; RooRealVar* obs = ((RooRealVar*)obstmp->first()); if(verbose) obs->Print(); //double expected = pdftmp->expectedEvents(*obstmp); // set value to desired value (this is just an example) // double obsVal = obs->getVal(); // set obs to desired value of observable // obs->setVal( obsVal ); //double fracAtObsValue = pdftmp->getVal(*obstmp); // get num events expected in bin for obsVal // double nu = expected * fracAtObsValue; // an easier way to get n TH1* histForN = dataForChan->createHistogram("HhstForN",*obs); for(int i=1; i<=histForN->GetNbinsX(); ++i){ double n = histForN->GetBinContent(i); if(verbose) std::cout << "n" << i << " = " << n << std::endl; ChannelBinDataMap[ ChannelName ].push_back( n ); } delete histForN; } // End Loop Over Categories delete iter; return; } int getStatUncertaintyConstraintTerm( RooArgList* constraints, RooRealVar* gamma_stat, RooAbsReal*& pois_nom, RooRealVar*& tau ) { // Given a set of constraint terms, // find the poisson constraint for the // given gamma and return the mean // as well as the 'tau' parameter bool verbose=false; // To get the constraint term, loop over all constraint terms // and look for the gamma_stat name as well as '_constraint' // std::string constraintTermName = std::string(gamma_stat->GetName()) + "_constraint"; TIterator* iter_list = constraints->createIterator(); RooAbsArg* term_constr=NULL; bool FoundConstraintTerm=false; RooAbsPdf* constraintTerm=NULL; while((term_constr=(RooAbsArg*)iter_list->Next())) { std::string TermName = term_constr->GetName(); // std::cout << "Checking if is a constraint term: " << TermName << std::endl; //if( TermName.find(gamma_stat->GetName())!=string::npos ) { if( term_constr->dependsOn( *gamma_stat) ) { if( TermName.find("_constraint")!=std::string::npos ) { FoundConstraintTerm=true; constraintTerm = (RooAbsPdf*) term_constr; break; } } } if( FoundConstraintTerm==false ) { std::cout << "Error: Couldn't find constraint term for parameter: " << gamma_stat->GetName() << " among constraints: " << constraints->GetName() << std::endl; constraints->Print("V"); throw std::runtime_error("Failed to find Gamma ConstraintTerm"); return -1; } delete iter_list; /* RooAbsPdf* constraintTerm = (RooAbsPdf*) constraints->find( constraintTermName.c_str() ); if( constraintTerm == NULL ) { std::cout << "Error: Couldn't find constraint term: " << constraintTermName << " for parameter: " << gamma_stat->GetName() << std::endl; throw std::runtime_error("Failed to find Gamma ConstraintTerm"); return -1; } */ // Find the "data" of the poisson term // This is the nominal value bool FoundNomMean=false; TIterator* iter_pois = constraintTerm->serverIterator(); //constraint_args RooAbsArg* term_pois ; while((term_pois=(RooAbsArg*)iter_pois->Next())) { std::string serverName = term_pois->GetName(); //std::cout << "Checking Server: " << serverName << std::endl; if( serverName.find("nom_")!=std::string::npos ) { FoundNomMean = true; pois_nom = (RooRealVar*) term_pois; } } if( !FoundNomMean || !pois_nom ) { std::cout << "Error: Did not find Nominal Pois Mean parameter in gamma constraint term PoissonMean: " << constraintTerm->GetName() << std::endl; throw std::runtime_error("Failed to find Nom Pois Mean"); } else { if(verbose) std::cout << "Found Poisson 'data' term: " << pois_nom->GetName() << std::endl; } delete iter_pois; // Taking the constraint term (a Poisson), find // the "mean" which is the product: gamma*tau // Then, from that mean, find tau TIterator* iter_constr = constraintTerm->serverIterator(); //constraint_args RooAbsArg* pois_mean_arg=NULL; bool FoundPoissonMean = false; while(( pois_mean_arg = (RooAbsArg*) iter_constr->Next() )) { std::string serverName = pois_mean_arg->GetName(); if( pois_mean_arg->dependsOn( *gamma_stat ) ) { FoundPoissonMean=true; // pois_mean = (RooAbsReal*) pois_mean_arg; break; } } if( !FoundPoissonMean || !pois_mean_arg ) { std::cout << "Error: Did not find PoissonMean parameter in gamma constraint term: " << constraintTerm->GetName() << std::endl; throw std::runtime_error("Failed to find PoissonMean"); return -1; } else { if(verbose) std::cout << "Found Poisson 'mean' term: " << pois_mean_arg->GetName() << std::endl; } delete iter_constr; TIterator* iter_product = pois_mean_arg->serverIterator(); //constraint_args RooAbsArg* term_in_product ; bool FoundTau=false; while((term_in_product=(RooAbsArg*)iter_product->Next())) { std::string serverName = term_in_product->GetName(); //std::cout << "Checking Server: " << serverName << std::endl; if( serverName.find("_tau")!=std::string::npos ) { FoundTau = true; tau = (RooRealVar*) term_in_product; } } if( !FoundTau || !tau ) { std::cout << "Error: Did not find Tau parameter in gamma constraint term PoissonMean: " << pois_mean_arg->GetName() << std::endl; throw std::runtime_error("Failed to find Tau"); } else { if(verbose) std::cout << "Found Poisson 'tau' term: " << tau->GetName() << std::endl; } delete iter_product; return 0; } } // close RooStats namespace } // close HistFactory namespace