00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "RooFit.h"
00029
00030 #include "Riostream.h"
00031 #include <math.h>
00032 #include <memory>
00033
00034 #include "RooAddition.h"
00035 #include "RooProduct.h"
00036 #include "RooAbsReal.h"
00037 #include "RooErrorHandler.h"
00038 #include "RooArgSet.h"
00039 #include "RooNameReg.h"
00040 #include "RooNLLVar.h"
00041 #include "RooChi2Var.h"
00042 #include "RooMsgService.h"
00043
00044 ClassImp(RooAddition)
00045 ;
00046
00047
00048
00049 RooAddition::RooAddition()
00050 : _setIter( _set.createIterator() )
00051 {
00052 }
00053
00054
00055
00056
00057 RooAddition::RooAddition(const char* name, const char* title, const RooArgSet& sumSet, Bool_t takeOwnership)
00058 : RooAbsReal(name, title)
00059 , _set("!set","set of components",this)
00060 , _setIter( _set.createIterator() )
00061 , _cacheMgr(this,10)
00062 {
00063
00064
00065
00066
00067 std::auto_ptr<TIterator> inputIter( sumSet.createIterator() );
00068 RooAbsArg* comp ;
00069 while((comp = (RooAbsArg*)inputIter->Next())) {
00070 if (!dynamic_cast<RooAbsReal*>(comp)) {
00071 coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp->GetName()
00072 << " is not of type RooAbsReal" << endl ;
00073 RooErrorHandler::softAbort() ;
00074 }
00075 _set.add(*comp) ;
00076 if (takeOwnership) _ownedList.addOwned(*comp) ;
00077 }
00078
00079 }
00080
00081
00082
00083
00084 RooAddition::RooAddition(const char* name, const char* title, const RooArgList& sumSet1, const RooArgList& sumSet2, Bool_t takeOwnership)
00085 : RooAbsReal(name, title)
00086 , _set("!set","set of components",this)
00087 , _setIter( _set.createIterator() )
00088 , _cacheMgr(this,10)
00089 {
00090
00091
00092
00093
00094
00095
00096 if (sumSet1.getSize() != sumSet2.getSize()) {
00097 coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << endl ;
00098 RooErrorHandler::softAbort() ;
00099 }
00100
00101 std::auto_ptr<TIterator> inputIter1( sumSet1.createIterator() );
00102 std::auto_ptr<TIterator> inputIter2( sumSet2.createIterator() );
00103 RooAbsArg *comp1(0),*comp2(0) ;
00104 while((comp1 = (RooAbsArg*)inputIter1->Next())) {
00105 if (!dynamic_cast<RooAbsReal*>(comp1)) {
00106 coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp1->GetName()
00107 << " in first list is not of type RooAbsReal" << endl ;
00108 RooErrorHandler::softAbort() ;
00109 }
00110 comp2 = (RooAbsArg*)inputIter2->Next();
00111 if (!dynamic_cast<RooAbsReal*>(comp2)) {
00112 coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp2->GetName()
00113 << " in first list is not of type RooAbsReal" << endl ;
00114 RooErrorHandler::softAbort() ;
00115 }
00116
00117 TString _name(name);
00118 _name.Append( "_[");
00119 _name.Append(comp1->GetName());
00120 _name.Append( "_x_");
00121 _name.Append(comp2->GetName());
00122 _name.Append( "]");
00123 RooProduct *prod = new RooProduct( _name, _name , RooArgSet(*comp1, *comp2) ) ;
00124 _set.add(*prod);
00125 _ownedList.addOwned(*prod) ;
00126 if (takeOwnership) {
00127 _ownedList.addOwned(*comp1) ;
00128 _ownedList.addOwned(*comp2) ;
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136 RooAddition::RooAddition(const RooAddition& other, const char* name)
00137 : RooAbsReal(other, name)
00138 , _set("!set",this,other._set)
00139 , _setIter( _set.createIterator() )
00140 , _cacheMgr(other._cacheMgr,this)
00141 {
00142
00143
00144
00145 }
00146
00147
00148
00149 RooAddition::~RooAddition()
00150 {
00151 delete _setIter ;
00152 }
00153
00154
00155 Double_t RooAddition::evaluate() const
00156 {
00157
00158 Double_t sum(0);
00159 const RooArgSet* nset = _set.nset() ;
00160
00161 _setIter->Reset() ;
00162 RooAbsReal* comp ;
00163 while((comp=(RooAbsReal*)_setIter->Next())) {
00164 sum += comp->getVal(nset) ;
00165 }
00166 return sum ;
00167 }
00168
00169
00170 Double_t RooAddition::defaultErrorLevel() const
00171 {
00172
00173
00174
00175
00176
00177
00178
00179
00180 RooAbsReal* nllArg(0) ;
00181 RooAbsReal* chi2Arg(0) ;
00182
00183 RooAbsArg* arg ;
00184
00185 _setIter->Reset() ;
00186 while((arg=(RooAbsArg*)_setIter->Next())) {
00187 if (dynamic_cast<RooNLLVar*>(arg)) {
00188 nllArg = (RooAbsReal*)arg ;
00189 }
00190 if (dynamic_cast<RooChi2Var*>(arg)) {
00191 chi2Arg = (RooAbsReal*)arg ;
00192 }
00193 }
00194
00195 if (nllArg && !chi2Arg) {
00196 coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName()
00197 << ") Summation contains a RooNLLVar, using its error level" << endl ;
00198 return nllArg->defaultErrorLevel() ;
00199 } else if (chi2Arg && !nllArg) {
00200 coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName()
00201 << ") Summation contains a RooChi2Var, using its error level" << endl ;
00202 return chi2Arg->defaultErrorLevel() ;
00203 } else if (!nllArg && !chi2Arg) {
00204 coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: "
00205 << "Summation contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
00206 } else {
00207 coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: "
00208 << "Summation contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
00209 }
00210
00211 return 1.0 ;
00212 }
00213
00214
00215
00216 void RooAddition::printMetaArgs(ostream& os) const
00217 {
00218 _setIter->Reset() ;
00219
00220 Bool_t first(kTRUE) ;
00221 RooAbsArg* arg;
00222 while((arg=(RooAbsArg*)_setIter->Next())) {
00223 if (!first) { os << " + " ;
00224 } else { first = kFALSE ;
00225 }
00226 os << arg->GetName() ;
00227 }
00228 os << " " ;
00229 }
00230
00231
00232 Int_t RooAddition::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const
00233 {
00234
00235
00236 analVars.add(allVars);
00237
00238
00239 Int_t sterileIndex(-1);
00240 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(&analVars,&analVars,&sterileIndex,RooNameReg::ptr(rangeName));
00241 if (cache!=0) {
00242 Int_t code = _cacheMgr.lastIndex();
00243 return code+1;
00244 }
00245
00246
00247 cache = new CacheElem;
00248 _setIter->Reset();
00249 RooAbsReal *arg(0);
00250 while( (arg=(RooAbsReal*)_setIter->Next())!=0 ) {
00251 RooAbsReal *I = arg->createIntegral(analVars,rangeName);
00252 cache->_I.addOwned(*I);
00253 }
00254
00255 Int_t code = _cacheMgr.setObj(&analVars,&analVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName));
00256 return 1+code;
00257 }
00258
00259
00260 Double_t RooAddition::analyticalIntegral(Int_t code, const char* rangeName) const
00261 {
00262
00263
00264
00265 CacheElem *cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1);
00266 if (cache==0) {
00267
00268 std::auto_ptr<RooArgSet> vars( getParameters(RooArgSet()) );
00269 std::auto_ptr<RooArgSet> iset( _cacheMgr.nameSet2ByIndex(code-1)->select(*vars) );
00270 RooArgSet dummy;
00271 Int_t code2 = getAnalyticalIntegral(*iset,dummy,rangeName);
00272 assert(code==code2);
00273 return analyticalIntegral(code2,rangeName);
00274 }
00275 assert(cache!=0);
00276
00277
00278 std::auto_ptr<TIterator> iter( cache->_I.createIterator() );
00279 RooAbsReal *I;
00280 double result(0);
00281 while ( ( I=(RooAbsReal*)iter->Next() ) != 0 ) result += I->getVal();
00282 return result;
00283
00284 }
00285
00286
00287 RooArgList RooAddition::CacheElem::containedArgs(Action)
00288 {
00289
00290 RooArgList ret(_I) ;
00291 return ret ;
00292 }
00293
00294 RooAddition::CacheElem::~CacheElem()
00295 {
00296
00297 }
00298
00299