PiecewiseInterpolation.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003  *****************************************************************************/
00004 
00005 //////////////////////////////////////////////////////////////////////////////
00006 // 
00007 // BEGIN_HTML
00008 // PiecewiseInterpolation 
00009 // END_HTML
00010 //
00011 
00012 
00013 #include "RooFit.h"
00014 
00015 #include "Riostream.h"
00016 #include "Riostream.h"
00017 #include <math.h>
00018 
00019 #include "RooStats/HistFactory/PiecewiseInterpolation.h"
00020 #include "RooAbsReal.h"
00021 #include "RooAbsPdf.h"
00022 #include "RooErrorHandler.h"
00023 #include "RooArgSet.h"
00024 #include "RooNLLVar.h"
00025 #include "RooChi2Var.h"
00026 #include "RooMsgService.h"
00027 
00028 ClassImp(PiecewiseInterpolation)
00029 ;
00030 
00031 
00032 //_____________________________________________________________________________
00033 PiecewiseInterpolation::PiecewiseInterpolation()
00034 {
00035   _lowIter = _lowSet.createIterator() ;
00036   _highIter = _highSet.createIterator() ;
00037   _paramIter = _paramSet.createIterator() ;
00038   _positiveDefinite=false;
00039 }
00040 
00041 
00042 
00043 //_____________________________________________________________________________
00044 PiecewiseInterpolation::PiecewiseInterpolation(const char* name, const char* title, const RooAbsReal& nominal,
00045                                                const RooArgList& lowSet, 
00046                                                const RooArgList& highSet,
00047                                                const RooArgList& paramSet,
00048                                                Bool_t takeOwnership) :
00049   RooAbsReal(name, title),
00050   _nominal("!nominal","nominal value", this, (RooAbsReal&)nominal),
00051   _lowSet("!lowSet","low-side variation",this),
00052   _highSet("!highSet","high-side variation",this),
00053   _paramSet("!paramSet","high-side variation",this),
00054   _positiveDefinite(false)
00055 {
00056   // Constructor with two set of RooAbsReals. The value of the function will be
00057   //
00058   //  A = sum_i lowSet(i)*highSet(i) 
00059   //
00060   // If takeOwnership is true the PiecewiseInterpolation object will take ownership of the arguments in sumSet
00061 
00062   _lowIter = _lowSet.createIterator() ;
00063   _highIter = _highSet.createIterator() ;
00064   _paramIter = _paramSet.createIterator() ;
00065 
00066   // KC: check both sizes
00067   if (lowSet.getSize() != highSet.getSize()) {
00068     coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << endl ;
00069     RooErrorHandler::softAbort() ;    
00070   }
00071 
00072   TIterator* inputIter1 = lowSet.createIterator() ;
00073   RooAbsArg* comp ;
00074   while((comp = (RooAbsArg*)inputIter1->Next())) {
00075     if (!dynamic_cast<RooAbsReal*>(comp)) {
00076       coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName() 
00077                             << " in first list is not of type RooAbsReal" << endl ;
00078       RooErrorHandler::softAbort() ;
00079     }
00080     _lowSet.add(*comp) ;
00081     if (takeOwnership) {
00082       _ownedList.addOwned(*comp) ;
00083     }
00084   }
00085   delete inputIter1 ;
00086 
00087 
00088   TIterator* inputIter2 = highSet.createIterator() ;
00089   while((comp = (RooAbsArg*)inputIter2->Next())) {
00090     if (!dynamic_cast<RooAbsReal*>(comp)) {
00091       coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName() 
00092                             << " in first list is not of type RooAbsReal" << endl ;
00093       RooErrorHandler::softAbort() ;
00094     }
00095     _highSet.add(*comp) ;
00096     if (takeOwnership) {
00097       _ownedList.addOwned(*comp) ;
00098     }
00099   }
00100   delete inputIter2 ;
00101 
00102 
00103   TIterator* inputIter3 = paramSet.createIterator() ;
00104   while((comp = (RooAbsArg*)inputIter3->Next())) {
00105     if (!dynamic_cast<RooAbsReal*>(comp)) {
00106       coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName() 
00107                             << " in first list is not of type RooAbsReal" << endl ;
00108       RooErrorHandler::softAbort() ;
00109     }
00110     _paramSet.add(*comp) ;
00111     if (takeOwnership) {
00112       _ownedList.addOwned(*comp) ;
00113     }
00114   }
00115   delete inputIter3 ;
00116 }
00117 
00118 
00119 
00120 //_____________________________________________________________________________
00121 PiecewiseInterpolation::PiecewiseInterpolation(const PiecewiseInterpolation& other, const char* name) :
00122   RooAbsReal(other, name), 
00123   _nominal("!nominal",this,other._nominal),
00124   _lowSet("!lowSet",this,other._lowSet),
00125   _highSet("!highSet",this,other._highSet),
00126   _paramSet("!paramSet",this,other._paramSet),
00127   _positiveDefinite(other._positiveDefinite)
00128 {
00129   // Copy constructor
00130 
00131   _lowIter = _lowSet.createIterator() ;
00132   _highIter = _highSet.createIterator() ;
00133   _paramIter = _paramSet.createIterator() ;
00134   
00135   // Member _ownedList is intentionally not copy-constructed -- ownership is not transferred
00136 }
00137 
00138 
00139 
00140 //_____________________________________________________________________________
00141 PiecewiseInterpolation::~PiecewiseInterpolation() 
00142 {
00143   // Destructor
00144 
00145   if (_lowIter) delete _lowIter ;
00146   if (_highIter) delete _highIter ;
00147   if (_paramIter) delete _paramIter ;
00148 }
00149 
00150 
00151 
00152 
00153 //_____________________________________________________________________________
00154 Double_t PiecewiseInterpolation::evaluate() const 
00155 {
00156   // Calculate and return current value of self
00157 
00158   ///////////////////
00159   Double_t nominal = _nominal;
00160   Double_t sum(nominal) ;
00161   _lowIter->Reset() ;
00162   _highIter->Reset() ;
00163   _paramIter->Reset() ;
00164   
00165 
00166   RooAbsReal* param ;
00167   RooAbsReal* high ;
00168   RooAbsReal* low ;
00169   //  const RooArgSet* nset = _paramList.nset() ;
00170   int i=0;
00171 
00172   while((param=(RooAbsReal*)_paramIter->Next())) {
00173     low = (RooAbsReal*)_lowIter->Next() ;
00174     high = (RooAbsReal*)_highIter->Next() ;
00175 
00176     
00177     if(param->getVal()>0)
00178       sum += param->getVal()*(high->getVal() - nominal );
00179     else
00180       sum += param->getVal()*(nominal - low->getVal());
00181 
00182     ++i;
00183   }
00184 
00185   if(_positiveDefinite && (sum<0)){
00186      sum = 1e-6;
00187   }
00188   return sum;
00189 
00190 }
00191 
00192 
00193 //_____________________________________________________________________________
00194 Int_t PiecewiseInterpolation::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, 
00195                                                       const RooArgSet* normSet, const char* /*rangeName*/) const 
00196 {
00197   // Advertise that all integrals can be handled internally.
00198 
00199   /*
00200   cout << "---------------------------\nin PiecewiseInterpolation get analytic integral " <<endl;
00201   cout << "all vars = "<<endl;
00202   allVars.Print("v");
00203   cout << "anal vars = "<<endl;
00204   analVars.Print("v");
00205   cout << "normset vars = "<<endl;
00206   if(normSet2)
00207     normSet2->Print("v");
00208   */
00209 
00210 
00211   // Handle trivial no-integration scenario
00212   if (allVars.getSize()==0) return 0 ;
00213   if (_forceNumInt) return 0 ;
00214 
00215 
00216   // Select subset of allVars that are actual dependents
00217   analVars.add(allVars) ;
00218   //  RooArgSet* normSet = normSet2 ? getObservables(normSet2) : 0 ;
00219   //  RooArgSet* normSet = getObservables();
00220   //  RooArgSet* normSet = 0;
00221 
00222 
00223   // Check if this configuration was created before
00224   Int_t sterileIdx(-1) ;
00225   CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx,0) ;
00226   if (cache) {
00227     return _normIntMgr.lastIndex()+1 ;
00228   }
00229   
00230   // Create new cache element
00231   cache = new CacheElem ;
00232 
00233   // Make list of function projection and normalization integrals 
00234   RooAbsReal* param ;
00235   RooAbsReal *func ;
00236   //  const RooArgSet* nset = _paramList.nset() ;
00237 
00238   // do nominal
00239   func = (RooAbsReal*)(&_nominal.arg()) ;
00240   RooAbsReal* funcInt = func->createIntegral(analVars) ;
00241   cache->_funcIntList.addOwned(*funcInt) ;
00242 
00243   // do variations
00244   _lowIter->Reset() ;
00245   _highIter->Reset() ;
00246   _paramIter->Reset() ;
00247   int i=0;
00248   while((param=(RooAbsReal*)_paramIter->Next())) {
00249     func = (RooAbsReal*)_lowIter->Next() ;
00250     funcInt = func->createIntegral(analVars) ;
00251     cache->_lowIntList.addOwned(*funcInt) ;
00252 
00253     func = (RooAbsReal*)_highIter->Next() ;
00254     funcInt = func->createIntegral(analVars) ;
00255     cache->_highIntList.addOwned(*funcInt) ;
00256 
00257     ++i;
00258   }
00259 
00260   // Store cache element
00261   Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,0) ;
00262 
00263   return code+1 ; 
00264 }
00265 
00266 
00267 
00268 
00269 //_____________________________________________________________________________
00270 Double_t PiecewiseInterpolation::analyticalIntegralWN(Int_t code, const RooArgSet* /*normSet2*/,const char* /*rangeName*/) const 
00271 {
00272   // Implement analytical integrations by doing appropriate weighting from  component integrals
00273   // functions to integrators of components
00274 
00275   CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
00276 
00277   TIterator* funcIntIter = cache->_funcIntList.createIterator() ;
00278   TIterator* lowIntIter = cache->_lowIntList.createIterator() ;
00279   TIterator* highIntIter = cache->_highIntList.createIterator() ;
00280   RooAbsReal *funcInt(0), *low(0), *high(0), *param(0) ;
00281   Double_t value(0) ;
00282   Double_t nominal(0);
00283 
00284   // get nominal 
00285   int i=0;
00286   while(( funcInt = (RooAbsReal*)funcIntIter->Next())) {
00287     value += funcInt->getVal() ;
00288     nominal = value;
00289     i++;
00290   }
00291   if(i==0 || i>1)
00292     cout << "problem, wrong number of nominal functions"<<endl;
00293 
00294   // now get low/high variations
00295   i = 0;
00296   _paramIter->Reset() ;
00297   while((param=(RooAbsReal*)_paramIter->Next())) {
00298     low = (RooAbsReal*)lowIntIter->Next() ;
00299     high = (RooAbsReal*)highIntIter->Next() ;
00300 
00301     
00302     if(param->getVal()>0)
00303       value += param->getVal()*(high->getVal() - nominal );
00304     else
00305       value += param->getVal()*(nominal - low->getVal());
00306 
00307     ++i;
00308   }
00309 
00310   return value;
00311 
00312 }
00313 
00314 
00315 /*
00316 //_____________________________________________________________________________
00317 void PiecewiseInterpolation::printMetaArgs(ostream& os) const 
00318 {
00319   // Customized printing of arguments of a PiecewiseInterpolation to more intuitively reflect the contents of the
00320   // product operator construction
00321 
00322   _lowIter->Reset() ;
00323   if (_highIter) {
00324     _highIter->Reset() ;
00325   }
00326 
00327   Bool_t first(kTRUE) ;
00328     
00329   RooAbsArg* arg1, *arg2 ;
00330   if (_highSet.getSize()!=0) { 
00331 
00332     while((arg1=(RooAbsArg*)_lowIter->Next())) {
00333       if (!first) {
00334         os << " + " ;
00335       } else {
00336         first = kFALSE ;
00337       }
00338       arg2=(RooAbsArg*)_highIter->Next() ;
00339       os << arg1->GetName() << " * " << arg2->GetName() ;
00340     }
00341 
00342   } else {
00343     
00344     while((arg1=(RooAbsArg*)_lowIter->Next())) {
00345       if (!first) {
00346         os << " + " ;
00347       } else {
00348         first = kFALSE ;
00349       }
00350       os << arg1->GetName() ; 
00351     }  
00352 
00353   }
00354 
00355   os << " " ;    
00356 }
00357 
00358 */

Generated on Tue Jul 5 14:52:35 2011 for ROOT_528-00b_version by  doxygen 1.5.1