RooAbsCollection.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAbsCollection.cxx 36230 2010-10-09 20:21:02Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 // 
00019 // BEGIN_HTML
00020 // RooAbsCollection is an abstract container object that can hold
00021 // multiple RooAbsArg objects.  Collections are ordered and can
00022 // contain multiple objects of the same name, (but a derived
00023 // implementation can enforce unique names). The storage of objects in
00024 // implement through class RooLinkedList, a doubly linked list with an
00025 // an optional hash-table lookup mechanism for fast indexing of large
00026 // collections. 
00027 // END_HTML
00028 //
00029 //
00030 
00031 #include "RooFit.h"
00032 
00033 #include "Riostream.h"
00034 #include "Riostream.h"
00035 #include <iomanip>
00036 #include <fstream>
00037 #include <vector>
00038 #include <string>
00039 #include "TClass.h"
00040 #include "TStopwatch.h"
00041 #include "TRegexp.h"
00042 #include "RooAbsCollection.h"
00043 #include "RooStreamParser.h"
00044 #include "RooFormula.h"
00045 #include "RooAbsRealLValue.h"
00046 #include "RooAbsCategoryLValue.h"
00047 #include "RooStringVar.h"
00048 #include "RooTrace.h"
00049 #include "RooArgList.h"
00050 #include "RooLinkedListIter.h"
00051 #include "RooCmdConfig.h"
00052 #include "RooRealVar.h"
00053 #include "RooGlobalFunc.h"
00054 #include "RooMsgService.h"
00055 #include <string>
00056 #include <sstream>
00057 using namespace std ;
00058 
00059 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
00060 char* operator+( streampos&, char* );
00061 #endif
00062 
00063 ClassImp(RooAbsCollection)
00064   ;
00065 
00066 //_____________________________________________________________________________
00067 RooAbsCollection::RooAbsCollection() :
00068   _list(43),
00069   _ownCont(kFALSE), 
00070   _name()
00071 {
00072   // Default constructor
00073 
00074   RooTrace::create(this) ;
00075 }
00076 
00077 
00078 
00079 //_____________________________________________________________________________
00080 RooAbsCollection::RooAbsCollection(const char *name) :
00081   _list(43),
00082   _ownCont(kFALSE), 
00083   _name(name)
00084 {
00085   // Empty collection constructor
00086 
00087   RooTrace::create(this) ;
00088 }
00089 
00090 
00091 
00092 //_____________________________________________________________________________
00093 RooAbsCollection::RooAbsCollection(const RooAbsCollection& other, const char *name) :
00094   TObject(other),
00095   RooPrintable(other),
00096   _list(other._list.getHashTableSize()) , 
00097   _ownCont(kFALSE), 
00098   _name(name)
00099 {
00100   // Copy constructor. Note that a copy of a collection is always non-owning,
00101   // even the source collection is owning. To create an owning copy of
00102   // a collection (owning or not), use the snaphot() method.
00103 
00104   RooTrace::create(this) ;
00105   if (!name) setName(other.GetName()) ;
00106   
00107   // Transfer contents (not owned)
00108   TIterator *iterator= other.createIterator();
00109   RooAbsArg *arg = 0;
00110   while((arg= (RooAbsArg*)iterator->Next())) {
00111     add(*arg);
00112   }
00113   delete iterator;
00114 }
00115 
00116 
00117 
00118 //_____________________________________________________________________________
00119 RooAbsCollection::~RooAbsCollection() 
00120 {
00121   // Destructor
00122 
00123   // Delete all variables in our list if we own them
00124   if(_ownCont){ 
00125     safeDeleteList() ;
00126     //_list.Delete();
00127   }
00128   RooTrace::destroy(this) ;
00129 }
00130 
00131 
00132 
00133 //_____________________________________________________________________________
00134 void RooAbsCollection::safeDeleteList() 
00135 {
00136   // Examine client server dependencies in list and
00137   // delete contents in safe order: any client
00138   // is deleted before a server is deleted
00139 
00140   // Handle trivial case here
00141   if (getSize()==1) {
00142     _list.Delete() ;
00143     return ;
00144   }
00145   
00146   TIterator* iter = createIterator() ;
00147   RooAbsArg* arg ;
00148   Bool_t working = kTRUE ;
00149 
00150   while(working) {
00151     working = kFALSE ;
00152     iter->Reset() ;
00153     while((arg=(RooAbsArg*)iter->Next())) {
00154 
00155       // Check if arg depends on remainder of list      
00156       if (!arg->dependsOn(*this,arg)) {
00157         // Otherwise leave it our and delete it 
00158         remove(*arg) ;
00159         delete arg ;
00160         working = kTRUE ;
00161       } 
00162     }
00163     if (_list.GetSize()<2) break ;
00164   }
00165   delete iter ;
00166 
00167   // Check if there are any remaining elements
00168   if (getSize()>1) {    
00169     coutW(ObjectHandling) << "RooAbsCollection::safeDeleteList(" << GetName() 
00170                           << ") WARNING: unable to delete following elements in client-server order " ;
00171     Print("1") ;
00172   }
00173 
00174   // Built-in delete remaining elements
00175   _list.Delete() ;
00176 }
00177 
00178 
00179 
00180 //_____________________________________________________________________________
00181 RooAbsCollection* RooAbsCollection::snapshot(Bool_t deepCopy) const
00182 {
00183   // Take a snap shot of current collection contents:
00184   // An owning collection is returned containing clones of 
00185   // 
00186   //     - Elements in this collection 
00187   //     - External dependents of all elements
00188   //       and recursively any dependents of those dependents
00189   //       (if deepCopy flag is set)
00190   //
00191   // If deepCopy is specified, the client-server links between the cloned
00192   // list elements and the cloned external dependents are reconnected to
00193   // each other, making the snapshot a completely self-contained entity.
00194   //
00195   //
00196 
00197   // First create empty list
00198   TString snapName ;
00199   if (TString(GetName()).Length()>0) {
00200     snapName.Append("Snapshot of ") ;
00201     snapName.Append(GetName()) ;
00202   }
00203   RooAbsCollection* output = (RooAbsCollection*) create(snapName.Data()) ;
00204   if (deepCopy || getSize()>100) {
00205     output->setHashTableSize(100) ;
00206   }
00207   Bool_t error = snapshot(*output,deepCopy) ;
00208   if (error) {
00209     delete output ;
00210     return 0 ;
00211   }
00212   return output ;
00213 }
00214 
00215 
00216 
00217 //_____________________________________________________________________________
00218 Bool_t RooAbsCollection::snapshot(RooAbsCollection& output, Bool_t deepCopy) const 
00219 {
00220   // Take a snap shot of current collection contents:
00221   // An owning collection is returned containing clones of 
00222   // 
00223   //     - Elements in this collection 
00224   //     - External dependents of all elements
00225   //       and recursively any dependents of those dependents
00226   //       (if deepCopy flag is set)
00227   //
00228   // If deepCopy is specified, the client-server links between the cloned
00229   // list elements and the cloned external dependents are reconnected to
00230   // each other, making the snapshot a completely self-contained entity.
00231   //
00232   //
00233 
00234   // Copy contents
00235   TIterator *iterator= createIterator();
00236   RooAbsArg *orig = 0;
00237   while((0 != (orig= (RooAbsArg*)iterator->Next()))) {
00238     RooAbsArg *copy= (RooAbsArg*)orig->Clone();
00239     output.add(*copy);
00240   }
00241   delete iterator;
00242 
00243   TIterator* vIter = output.createIterator() ;
00244   RooAbsArg* var ;
00245 
00246   // Add external dependents
00247   Bool_t error(kFALSE) ;
00248   if (deepCopy) {
00249     // Recursively add clones of all servers
00250     while ((var=(RooAbsArg*)vIter->Next())) {
00251       error |= output.addServerClonesToList(*var) ;
00252     }
00253   }
00254 
00255   // Handle eventual error conditions
00256   if (error) {
00257     coutE(ObjectHandling) << "RooAbsCollection::snapshot(): Errors occurred in deep clone process, snapshot not created" << endl ;
00258     output._ownCont = kTRUE ;    
00259     return kTRUE ;
00260   }
00261 
00262    // Redirect all server connections to internal list members
00263   vIter->Reset() ;
00264   while ((var=(RooAbsArg*)vIter->Next())) {
00265     var->redirectServers(output,deepCopy) ;
00266   }
00267   delete vIter ;
00268 
00269 
00270   // Transfer ownership of contents to list
00271   output._ownCont = kTRUE ;
00272   return kFALSE ;
00273 }
00274 
00275 
00276 
00277 //_____________________________________________________________________________
00278 Bool_t RooAbsCollection::addServerClonesToList(const RooAbsArg& var)
00279 {
00280   // Add clones of servers of given argument to list
00281 
00282   Bool_t ret(kFALSE) ;
00283 
00284   TIterator* sIter = var.serverIterator() ;
00285   RooAbsArg* server ;
00286   while ((server=(RooAbsArg*)sIter->Next())) {
00287     RooAbsArg* tmp = find(server->GetName()) ;
00288     if (!tmp) {
00289       RooAbsArg* serverClone = (RooAbsArg*)server->Clone() ;      
00290       serverClone->setAttribute("SnapShot_ExtRefClone") ;
00291       _list.Add(serverClone) ;      
00292       ret |= addServerClonesToList(*server) ;
00293     } else {
00294     }
00295   }
00296   delete sIter ;
00297   return ret ;
00298 }
00299 
00300 
00301 
00302 //_____________________________________________________________________________
00303 RooAbsCollection &RooAbsCollection::operator=(const RooAbsCollection& other) 
00304 {
00305   // The assignment operator sets the value of any argument in our set
00306   // that also appears in the other set.
00307 
00308   if (&other==this) return *this ;
00309 
00310   RooAbsArg *elem, *theirs ;
00311   RooLinkedListIter iter = _list.iterator() ;
00312   while((elem=(RooAbsArg*)iter.Next())) {
00313     theirs= other.find(elem->GetName());
00314     if(!theirs) continue;
00315     theirs->syncCache() ;
00316     elem->copyCache(theirs) ;
00317     elem->setAttribute("Constant",theirs->isConstant()) ;
00318   }
00319   return *this;
00320 }
00321 
00322 
00323 
00324 //_____________________________________________________________________________
00325 RooAbsCollection &RooAbsCollection::assignValueOnly(const RooAbsCollection& other) 
00326 {
00327   // The assignment operator sets the value of any argument in our set
00328   // that also appears in the other set.
00329 
00330   if (&other==this) return *this ;
00331 
00332   RooAbsArg *elem, *theirs ;
00333   RooLinkedListIter iter = _list.iterator() ;
00334   while((elem=(RooAbsArg*)iter.Next())) {
00335     theirs= other.find(elem->GetName());
00336     if(!theirs) continue;
00337     theirs->syncCache() ;
00338     elem->copyCache(theirs) ;
00339   }
00340   return *this;
00341 }
00342 
00343 
00344 
00345 //_____________________________________________________________________________
00346 RooAbsCollection &RooAbsCollection::assignFast(const RooAbsCollection& other) 
00347 {
00348   // Functional equivalent of operator=() but assumes this and other collection
00349   // have same layout. Also no attributes are copied
00350 
00351   if (&other==this) return *this ;
00352 
00353   RooAbsArg *elem, *theirs ;
00354   RooLinkedListIter iter = _list.iterator() ;
00355   RooLinkedListIter iter2 = other._list.iterator() ;
00356   while((elem=(RooAbsArg*)iter.Next())) {
00357 
00358     // Identical size of iterators is documented assumption of method
00359     // coverity[NULL_RETURNS]
00360     theirs= (RooAbsArg*)iter2.Next() ;
00361 
00362     theirs->syncCache() ;
00363     elem->copyCache(theirs,kTRUE) ;
00364   }
00365   return *this;
00366 }
00367 
00368 
00369 
00370 //_____________________________________________________________________________
00371 Bool_t RooAbsCollection::addOwned(RooAbsArg& var, Bool_t silent) 
00372 {
00373   // Add the specified argument to list. Returns kTRUE if successful, or
00374   // else kFALSE if a variable of the same name is already in the list.
00375   // This method can only be called on a list that is flagged as owning
00376   // all of its contents, or else on an empty list (which will force the
00377   // list into that mode).
00378 
00379   // check that we own our variables or else are empty
00380   if(!_ownCont && (getSize() > 0) && !silent) {
00381     coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addOwned: can only add to an owned list" << endl;
00382     return kFALSE;
00383   }
00384   _ownCont= kTRUE;
00385 
00386   _list.Add((RooAbsArg*)&var);
00387   return kTRUE;
00388 }
00389 
00390 
00391 
00392 //_____________________________________________________________________________
00393 RooAbsArg *RooAbsCollection::addClone(const RooAbsArg& var, Bool_t silent) 
00394 {
00395   // Add a clone of the specified argument to list. Returns a pointer to
00396   // the clone if successful, or else zero if a variable of the same name
00397   // is already in the list or the list does *not* own its variables (in
00398   // this case, try add() instead.) Calling addClone() on an empty list
00399   // forces it to take ownership of all its subsequent variables.
00400 
00401   // check that we own our variables or else are empty
00402   if(!_ownCont && (getSize() > 0) && !silent) {
00403     coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addClone: can only add to an owned list" << endl;
00404     return 0;
00405   }
00406   _ownCont= kTRUE;
00407 
00408   // add a pointer to a clone of this variable to our list (we now own it!)
00409   RooAbsArg *clone2= (RooAbsArg*)var.Clone();
00410   if(0 != clone2) _list.Add((RooAbsArg*)clone2);
00411 
00412   return clone2;
00413 }
00414 
00415 
00416 
00417 //_____________________________________________________________________________
00418 Bool_t RooAbsCollection::add(const RooAbsArg& var, Bool_t silent) 
00419 {
00420   // Add the specified argument to list. Returns kTRUE if successful, or
00421   // else kFALSE if a variable of the same name is already in the list
00422   // or the list owns its variables (in this case, try addClone() or addOwned() instead).
00423 
00424   // check that this isn't a copy of a list
00425   if(_ownCont && !silent) {
00426     coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::add: cannot add to an owned list" << endl;
00427     return kFALSE;
00428   }
00429 
00430   // add a pointer to this variable to our list (we don't own it!)
00431   _list.Add((RooAbsArg*)&var);
00432   return kTRUE;
00433 }
00434 
00435 
00436 
00437 //_____________________________________________________________________________
00438 Bool_t RooAbsCollection::add(const RooAbsCollection& list, Bool_t silent)
00439 {
00440   // Add a collection of arguments to this collection by calling add()
00441   // for each element in the source collection
00442 
00443   Bool_t result(false) ;
00444 
00445   Int_t n= list.getSize() ;
00446   for(Int_t index= 0; index < n; index++) {
00447     result |= add((RooAbsArg&)*list._list.At(index),silent) ;
00448   }
00449 
00450   return result;  
00451 }
00452 
00453 
00454 
00455 //_____________________________________________________________________________
00456 Bool_t RooAbsCollection::addOwned(const RooAbsCollection& list, Bool_t silent)
00457 {
00458   // Add a collection of arguments to this collection by calling addOwned()
00459   // for each element in the source collection
00460 
00461   Bool_t result(false) ;
00462 
00463   Int_t n= list.getSize() ;
00464   for(Int_t index= 0; index < n; index++) {
00465     result |= addOwned((RooAbsArg&)*list._list.At(index),silent) ;
00466   }
00467 
00468   return result;  
00469 }
00470 
00471 
00472 
00473 //_____________________________________________________________________________
00474 void RooAbsCollection::addClone(const RooAbsCollection& list, Bool_t silent)
00475 {
00476   // Add a collection of arguments to this collection by calling addOwned()
00477   // for each element in the source collection
00478 
00479   Int_t n= list.getSize() ;
00480   for(Int_t index= 0; index < n; index++) {
00481     addClone((RooAbsArg&)*list._list.At(index),silent) ;
00482   }
00483 }
00484 
00485 
00486 
00487 //_____________________________________________________________________________
00488 Bool_t RooAbsCollection::replace(const RooAbsCollection &other) 
00489 {
00490   // Replace any args in our set with args of the same name from the other set
00491   // and return kTRUE for success. Fails if this list is a copy of another.
00492 
00493   // check that this isn't a copy of a list
00494   if(_ownCont) {
00495     coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << endl;
00496     return kFALSE;
00497   }
00498 
00499   // loop over elements in the other list
00500   TIterator *otherArgs= other.createIterator();
00501   const RooAbsArg *arg = 0;
00502   while((arg= (const RooAbsArg*)otherArgs->Next())) {
00503 
00504     // do we have an arg of the same name in our set?
00505     RooAbsArg *found= find(arg->GetName());
00506     if(found) replace(*found,*arg);
00507   }
00508   delete otherArgs;
00509   return kTRUE;
00510 }
00511 
00512 
00513 
00514 //_____________________________________________________________________________
00515 Bool_t RooAbsCollection::replace(const RooAbsArg& var1, const RooAbsArg& var2) 
00516 {
00517   // Replace var1 with var2 and return kTRUE for success. Fails if
00518   // this list is a copy of another, if var1 is not already in this set,
00519   // or if var2 is already in this set. var1 and var2 do not need to have
00520   // the same name.
00521 
00522   // check that this isn't a copy of a list
00523   if(_ownCont) {
00524     coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << endl;
00525     return kFALSE;
00526   }
00527 
00528   // is var1 already in this list?
00529   const char *name= var1.GetName();
00530 
00531   Bool_t foundVar1(kFALSE) ;
00532   TIterator* iter = createIterator() ;
00533   RooAbsArg* arg ;
00534   while((arg=(RooAbsArg*)iter->Next())) {
00535     if (arg==&var1) foundVar1=kTRUE ;
00536   }
00537   delete iter ;
00538   if (!foundVar1) {
00539     coutE(ObjectHandling) << "RooAbsCollection: variable \"" << name << "\" is not in the list"
00540          << " and cannot be replaced" << endl;
00541     return kFALSE;
00542   }
00543 
00544   RooAbsArg *other ;
00545 
00546   // is var2's name already in this list?
00547   if (dynamic_cast<RooArgSet*>(this)) {
00548     other= find(var2.GetName());
00549     if(other != 0 && other != &var1) {
00550       coutE(ObjectHandling) << "RooAbsCollection: cannot replace \"" << name
00551            << "\" with already existing \"" << var2.GetName() << "\"" << endl;
00552       return kFALSE;
00553     }
00554   }
00555 
00556   // replace var1 with var2
00557   _list.Replace(&var1,&var2) ;
00558 //   _list.AddBefore((RooAbsArg*)&var1,(RooAbsArg*)&var2);
00559 //   _list.Remove((RooAbsArg*)&var1);
00560   return kTRUE;
00561 }
00562 
00563 
00564 
00565 //_____________________________________________________________________________
00566 Bool_t RooAbsCollection::remove(const RooAbsArg& var, Bool_t , Bool_t matchByNameOnly) 
00567 {
00568   // Remove the specified argument from our list. Return kFALSE if
00569   // the specified argument is not found in our list. An exact pointer
00570   // match is required, not just a match by name. A variable can be
00571   // removed from a copied list and will be deleted at the same time.
00572 
00573   // is var already in this list?
00574   TString name(var.GetName()) ;
00575   Bool_t anyFound(kFALSE) ;
00576 
00577   TIterator* iter = createIterator() ;
00578   RooAbsArg* arg ;
00579   while((arg=(RooAbsArg*)iter->Next())) {
00580     if ((&var)==arg) {
00581       _list.Remove(arg) ;
00582       anyFound=kTRUE ;
00583     } else if (matchByNameOnly) {
00584       if (!name.CompareTo(arg->GetName())) {
00585         _list.Remove(arg) ;
00586         anyFound=kTRUE ;
00587       }
00588     }
00589   }
00590   delete iter ;
00591   
00592   return anyFound ;
00593 }
00594 
00595 
00596 
00597 //_____________________________________________________________________________
00598 Bool_t RooAbsCollection::remove(const RooAbsCollection& list, Bool_t silent, Bool_t matchByNameOnly) 
00599 {
00600   // Remove each argument in the input list from our list using remove(const RooAbsArg&).
00601   // Return kFALSE in case of problems.
00602 
00603   Bool_t result(false) ;
00604 
00605   Int_t n= list.getSize() ;
00606   for(Int_t index= 0; index < n; index++) {
00607     result |= remove((RooAbsArg&)*list._list.At(index),silent,matchByNameOnly) ;
00608   }
00609 
00610   return result;
00611 }
00612 
00613 
00614 
00615 //_____________________________________________________________________________
00616 void RooAbsCollection::removeAll() 
00617 {
00618   // Remove all arguments from our set, deleting them if we own them.
00619   // This effectively restores our object to the state it would have
00620   // just after calling the RooAbsCollection(const char*) constructor.
00621 
00622   if(_ownCont) {
00623     safeDeleteList() ;
00624     _ownCont= kFALSE;
00625   }
00626   else {
00627     _list.Clear();
00628   }
00629 }
00630 
00631 
00632 
00633 //_____________________________________________________________________________
00634 void RooAbsCollection::setAttribAll(const Text_t* name, Bool_t value) 
00635 {
00636   // Set given attribute in each element of the collection by
00637   // calling each elements setAttribute() function.
00638 
00639   TIterator* iter= createIterator() ;
00640   RooAbsArg* arg ;
00641   while ((arg=(RooAbsArg*)iter->Next())) {
00642     arg->setAttribute(name,value) ;
00643   }
00644   delete iter ;
00645 }
00646 
00647 
00648 
00649 
00650 //_____________________________________________________________________________
00651 RooAbsCollection* RooAbsCollection::selectByAttrib(const char* name, Bool_t value) const
00652 {
00653   // Create a subset of the current collection, consisting only of those
00654   // elements with the specified attribute set. The caller is responsibe
00655   // for deleting the returned collection
00656 
00657   TString selName(GetName()) ;
00658   selName.Append("_selection") ;
00659   RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ;
00660   
00661   // Scan set contents for matching attribute
00662   TIterator* iter= createIterator() ;
00663   RooAbsArg* arg ;
00664   while ((arg=(RooAbsArg*)iter->Next())) {
00665     if (arg->getAttribute(name)==value)
00666       sel->add(*arg) ;
00667   }
00668   delete iter ;
00669 
00670   return sel ;
00671 }
00672 
00673 
00674 
00675 
00676 //_____________________________________________________________________________
00677 RooAbsCollection* RooAbsCollection::selectCommon(const RooAbsCollection& refColl) const 
00678 {
00679   // Create a subset of the current collection, consisting only of those
00680   // elements that are contained as well in the given reference collection.
00681   // The caller is responsible for deleting the returned collection
00682 
00683   // Create output set
00684   TString selName(GetName()) ;
00685   selName.Append("_selection") ;
00686   RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ; 
00687 
00688   // Scan set contents for matching attribute
00689   TIterator* iter= createIterator() ;
00690   RooAbsArg* arg ;
00691   while ((arg=(RooAbsArg*)iter->Next())) {
00692     if (refColl.find(arg->GetName()))
00693       sel->add(*arg) ;
00694   }
00695   delete iter ;
00696 
00697   return sel ;
00698 }
00699 
00700 
00701 
00702 //_____________________________________________________________________________
00703 RooAbsCollection* RooAbsCollection::selectByName(const char* nameList, Bool_t verbose) const 
00704 {
00705   // Create a subset of the current collection, consisting only of those
00706   // elements with names matching the wildcard expressions in nameList,
00707   // supplied as a comma separated list
00708 
00709   // Create output set
00710   TString selName(GetName()) ;
00711   selName.Append("_selection") ;
00712   RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ; 
00713   
00714   TIterator* iter = createIterator() ;
00715 
00716   char* buf = new char[strlen(nameList)+1] ;
00717   strlcpy(buf,nameList,strlen(nameList)+1) ;
00718   char* wcExpr = strtok(buf,",") ;
00719   while(wcExpr) {
00720     TRegexp rexp(wcExpr,kTRUE) ;
00721     if (verbose) {
00722       cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") processing expression '" << wcExpr << "'" << endl ;
00723     }
00724 
00725     iter->Reset() ;
00726     RooAbsArg* arg ;
00727     while((arg=(RooAbsArg*)iter->Next())) {
00728       if (TString(arg->GetName()).Index(rexp)>=0) {
00729         if (verbose) {
00730           cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") selected element " << arg->GetName() << endl ;
00731         }
00732         sel->add(*arg) ;
00733       }
00734     }
00735     wcExpr = strtok(0,",") ;
00736   }
00737   delete iter ;
00738   delete[] buf ;
00739 
00740   return sel ;
00741 }
00742 
00743 
00744 
00745 
00746 //_____________________________________________________________________________
00747 Bool_t RooAbsCollection::equals(const RooAbsCollection& otherColl) const
00748 {
00749   // Check if this and other collection have identically named contents
00750 
00751   // First check equal length 
00752   if (getSize() != otherColl.getSize()) return kFALSE ;
00753 
00754   // Then check that each element of our list also occurs in the other list
00755   TIterator* iter = createIterator() ;
00756   RooAbsArg* arg ;
00757   while((arg=(RooAbsArg*)iter->Next())) {
00758     if (!otherColl.find(arg->GetName())) {
00759       delete iter ;
00760       return kFALSE ;
00761     }
00762   }
00763   delete iter ;
00764   return kTRUE ;
00765 }
00766 
00767 
00768 
00769 
00770 //_____________________________________________________________________________
00771 Bool_t RooAbsCollection::overlaps(const RooAbsCollection& otherColl) const 
00772 {
00773   // Check if this and other collection have common entries
00774 
00775   TIterator* iter = createIterator() ;
00776   RooAbsArg* arg ;
00777   while((arg=(RooAbsArg*)iter->Next())) {
00778     if (otherColl.find(arg->GetName())) {
00779       delete iter ;
00780       return kTRUE ;
00781     }
00782   }
00783   delete iter ;
00784   return kFALSE ;
00785 }
00786 
00787 
00788 
00789 
00790 //_____________________________________________________________________________
00791 RooAbsArg *RooAbsCollection::find(const char *name) const 
00792 {
00793   // Find object with given name in list. A null pointer 
00794   // is returned if no object with the given name is found
00795 
00796   return (RooAbsArg*) _list.find(name);
00797 }
00798 
00799 
00800 
00801 //_____________________________________________________________________________
00802 string RooAbsCollection::contentsString() const 
00803 {
00804   // Return comma separated list of contained object names as STL string
00805 
00806   string retVal ;
00807   TIterator* iter = createIterator() ;
00808   RooAbsArg* arg ;
00809   Bool_t isFirst(kTRUE) ;
00810   while((arg=(RooAbsArg*)iter->Next())) {
00811     if (isFirst) {
00812       isFirst=kFALSE ;
00813     } else {
00814       retVal += "," ;
00815     }
00816     retVal += arg->GetName() ;
00817   }
00818   delete iter ;
00819   return retVal ;
00820 }
00821 
00822 
00823 
00824 //_____________________________________________________________________________
00825 void RooAbsCollection::printName(ostream& os) const 
00826 {
00827   // Return collection name
00828 
00829   os << GetName() ;
00830 }
00831 
00832 
00833 
00834 //_____________________________________________________________________________
00835 void RooAbsCollection::printTitle(ostream& os) const 
00836 {
00837   // Return collection title
00838 
00839   os << GetTitle() ;
00840 }
00841 
00842 
00843 
00844 //_____________________________________________________________________________
00845 void RooAbsCollection::printClassName(ostream& os) const 
00846 {
00847   // Return collection class name
00848 
00849   os << IsA()->GetName() ;
00850 }
00851 
00852 
00853 
00854 //_____________________________________________________________________________
00855 Int_t RooAbsCollection::defaultPrintContents(Option_t* opt) const 
00856 {
00857   // Define default RooPrinable print options for given Print() flag string
00858   // For inline printing only show value of objects, for default print show
00859   // name,class name value and extras of each object. In verbose mode
00860   // also add object adress, argument and title
00861   
00862   if (opt && TString(opt)=="I") {
00863     return kValue ;
00864   }
00865   if (opt && TString(opt).Contains("v")) {
00866     return kAddress|kName|kArgs|kClassName|kValue|kTitle|kExtras ;
00867   }
00868   return kName|kClassName|kValue ;
00869 }
00870 
00871 
00872 
00873 
00874 
00875 //_____________________________________________________________________________
00876 void RooAbsCollection::printValue(ostream& os) const
00877 {
00878   // Print value of collection, i.e. a comma separated list of contained
00879   // object names
00880 
00881   Bool_t first2(kTRUE) ;
00882   os << "(" ;
00883   TIterator* iter = createIterator() ;
00884   RooAbsArg* arg ;
00885   while((arg=(RooAbsArg*)iter->Next())) {
00886     if (!first2) {
00887       os << "," ;
00888     } else {
00889       first2 = kFALSE ;
00890     }
00891     os << arg->GetName() ;
00892     
00893   }
00894   os << ")" ;  
00895   delete iter ;
00896 }
00897 
00898 
00899 
00900 //_____________________________________________________________________________
00901 void RooAbsCollection::printMultiline(ostream&os, Int_t contents, Bool_t /*verbose*/, TString indent) const
00902 {
00903   // Implement multiline printin of collection, one line for each ontained object showing
00904   // the requested content
00905 
00906   if (TString(GetName()).Length()>0 && (contents&kCollectionHeader)) {
00907     os << indent << ClassName() << "::" << GetName() << ":" << (_ownCont?" (Owning contents)":"") << endl;
00908   }
00909 
00910   TIterator *iterator= createIterator();
00911   int index= 0;
00912   RooAbsArg *next = 0;
00913   TString deeper(indent);
00914   deeper.Append("     ");
00915   
00916   // Adjust the with of the name field to fit the largest name, if requesed
00917   Int_t maxNameLen(1) ;
00918   Int_t nameFieldLengthSaved = RooPrintable::_nameLength ;
00919   if (nameFieldLengthSaved==0) {
00920     while((next=(RooAbsArg*)iterator->Next())) {
00921       Int_t len = strlen(next->GetName()) ;
00922       if (len>maxNameLen) maxNameLen = len ;
00923     }
00924     iterator->Reset() ;
00925     RooPrintable::nameFieldLength(maxNameLen+1) ;
00926   }
00927   
00928   while((0 != (next= (RooAbsArg*)iterator->Next()))) {
00929     os << indent << setw(3) << ++index << ") ";
00930     next->printStream(os,contents,kSingleLine,"");
00931   }
00932   delete iterator;
00933   
00934   // Reset name field length, if modified
00935   RooPrintable::nameFieldLength(nameFieldLengthSaved) ;
00936 }
00937 
00938 
00939 
00940 //_____________________________________________________________________________
00941 void RooAbsCollection::dump() const 
00942 {
00943   // Base contents dumper for debugging purposes
00944 
00945   TIterator* iter = createIterator() ;
00946   RooAbsArg* arg ;
00947   while((arg=(RooAbsArg*)iter->Next())) {
00948     cout << arg << " " << arg->IsA()->GetName() << "::" << arg->GetName() << " (" << arg->GetTitle() << ")" << endl ;
00949   }
00950   delete iter ;
00951 }
00952 
00953 
00954 
00955 //_____________________________________________________________________________
00956 void RooAbsCollection::printLatex(const RooCmdArg& arg1, const RooCmdArg& arg2,
00957                                   const RooCmdArg& arg3, const RooCmdArg& arg4, 
00958                                   const RooCmdArg& arg5, const RooCmdArg& arg6, 
00959                                   const RooCmdArg& arg7, const RooCmdArg& arg8) const
00960 {
00961   // Output content of collection as LaTex table. By default a table with two columns is created: the left
00962   // column contains the name of each variable, the right column the value.
00963   //
00964   // The following optional named arguments can be used to modify the default behavior
00965   //
00966   //   Columns(Int_t ncol)                    -- Fold table into multiple columns, i.e. ncol=3 will result in 3 x 2 = 6 total columns
00967   //   Sibling(const RooAbsCollection& other) -- Define sibling list. The sibling list is assumed to have objects with the same
00968   //                                             name in the same order. If this is not the case warnings will be printed. If a single
00969   //                                             sibling list is specified, 3 columns will be output: the (common) name, the value of this
00970   //                                             list and the value in the sibling list. Multiple sibling lists can be specified by 
00971   //                                             repeating the Sibling() command. 
00972   //   Format(const char* str)                -- Classic format string, provided for backward compatibility
00973   //   Format(...)                            -- Formatting arguments, details are given below
00974   //   OutputFile(const char* fname)          -- Send output to file with given name rather than standard output
00975   //
00976   // The Format(const char* what,...) has the following structure
00977   //
00978   //   const char* what          -- Controls what is shown. "N" adds name, "E" adds error, 
00979   //                                "A" shows asymmetric error, "U" shows unit, "H" hides the value
00980   //   FixedPrecision(int n)     -- Controls precision, set fixed number of digits
00981   //   AutoPrecision(int n)      -- Controls precision. Number of shown digits is calculated from error 
00982   //                                + n specified additional digits (1 is sensible default)
00983   //   VerbatimName(Bool_t flag) -- Put variable name in a \verb+   + clause.
00984   //
00985   // Example use: list.printLatex(Columns(2), Format("NEU",AutoPrecision(1),VerbatimName()) ) ;
00986 
00987 
00988   
00989   // Define configuration for this method
00990   RooCmdConfig pc("RooAbsCollection::printLatex()") ;
00991   pc.defineInt("ncol","Columns",0,1) ;
00992   pc.defineString("outputFile","OutputFile",0,"") ;
00993   pc.defineString("format","Format",0,"NEYVU") ;
00994   pc.defineInt("sigDigit","Format",0,1) ;
00995   pc.defineObject("siblings","Sibling",0,0,kTRUE) ;
00996   pc.defineInt("dummy","FormatArgs",0,0) ;
00997   pc.defineMutex("Format","FormatArgs") ;
00998  
00999   // Stuff all arguments in a list
01000   RooLinkedList cmdList;
01001   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
01002   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
01003   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
01004   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
01005 
01006   // Process & check varargs 
01007   pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01008   if (!pc.ok(kTRUE)) {
01009     return ;
01010   }
01011 
01012   const char* outFile = pc.getString("outputFile") ;
01013   if (outFile && strlen(outFile)) {
01014     ofstream ofs(outFile) ;
01015     if (pc.hasProcessed("FormatArgs")) {
01016       RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
01017       formatCmd->addArg(RooFit::LatexTableStyle()) ;
01018       printLatex(ofs,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;    
01019     } else {
01020       printLatex(ofs,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
01021     }
01022   } else {
01023     if (pc.hasProcessed("FormatArgs")) {
01024       RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
01025       formatCmd->addArg(RooFit::LatexTableStyle()) ;
01026       printLatex(cout,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;    
01027     } else {
01028       printLatex(cout,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
01029     }
01030   }
01031 }
01032 
01033 
01034 
01035 
01036 //_____________________________________________________________________________
01037 void RooAbsCollection::printLatex(ostream& ofs, Int_t ncol, const char* option, Int_t sigDigit, const RooLinkedList& siblingList, const RooCmdArg* formatCmd) const 
01038 {
01039   // Internal implementation function of printLatex
01040 
01041   // Count number of rows to print
01042   Int_t nrow = (Int_t) (getSize() / ncol + 0.99) ;
01043   Int_t i,j,k ;
01044 
01045   // Sibling list do not need to print their name as it is supposed to be the same  
01046   TString sibOption ;
01047   RooCmdArg sibFormatCmd ;
01048   if (option) {
01049     sibOption = option ;
01050     sibOption.ReplaceAll("N","") ;
01051     sibOption.ReplaceAll("n","") ;
01052   } else {
01053     sibFormatCmd = *formatCmd ;
01054     TString tmp = formatCmd->_s[0] ;
01055     tmp.ReplaceAll("N","") ;    
01056     tmp.ReplaceAll("n","") ;    
01057     static char buf[100] ;
01058     strlcpy(buf,tmp.Data(),100) ;
01059     sibFormatCmd._s[0] = buf ;
01060   }
01061 
01062 
01063   // Make list of lists ;
01064   RooLinkedList listList ;
01065   listList.Add((RooAbsArg*)this) ;
01066   TIterator* sIter = siblingList.MakeIterator() ;
01067   RooAbsCollection* col ;
01068   while((col=(RooAbsCollection*)sIter->Next())) {
01069     listList.Add(col) ;
01070   }
01071   delete sIter ;
01072 
01073   RooLinkedList listListRRV ;
01074 
01075   // Make list of RRV-only components
01076   TIterator* lIter = listList.MakeIterator() ;
01077   RooArgList* prevList = 0 ;
01078   while((col=(RooAbsCollection*)lIter->Next())) {
01079     RooArgList* list = new RooArgList ;
01080     TIterator* iter = col->createIterator() ;
01081     RooAbsArg* arg ;
01082     while((arg=(RooAbsArg*)iter->Next())) {    
01083       
01084       RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
01085       if (rrv) {
01086         list->add(*rrv) ;
01087       } else {
01088         coutW(InputArguments) << "RooAbsCollection::printLatex: can only print RooRealVar in LateX, skipping non-RooRealVar object named "
01089              << arg->GetName() << endl ;      
01090       }
01091       if (prevList && TString(rrv->GetName()).CompareTo(prevList->at(list->getSize()-1)->GetName())) {
01092         coutW(InputArguments) << "RooAbsCollection::printLatex: WARNING: naming and/or ordering of sibling list is different" << endl ;
01093       }
01094     }
01095     delete iter ;
01096     listListRRV.Add(list) ;
01097     if (prevList && list->getSize() != prevList->getSize()) {
01098       coutW(InputArguments) << "RooAbsCollection::printLatex: ERROR: sibling list(s) must have same length as self" << endl ;
01099       delete list ;
01100       listListRRV.Delete() ;
01101       return ;
01102     }
01103     prevList = list ;
01104   }
01105 
01106   // Construct table header
01107   Int_t nlist = listListRRV.GetSize() ;
01108   TString subheader = "l" ;
01109   for (k=0 ; k<nlist ; k++) subheader += "c" ;
01110 
01111   TString header = "\\begin{tabular}{" ;
01112   for (j=0 ; j<ncol ; j++) {
01113     if (j>0) header += "|" ;
01114     header += subheader ;
01115   }
01116   header += "}" ;
01117   ofs << header << endl ;
01118 
01119 
01120   // Print contents, delegating actual printing to RooRealVar::format()
01121   for (i=0 ; i<nrow ; i++) {
01122     for (j=0 ; j<ncol ; j++) {
01123       for (k=0 ; k<nlist ; k++) {
01124         RooRealVar* par = (RooRealVar*) ((RooArgList*)listListRRV.At(k))->at(i+j*nrow) ;
01125         if (par) {
01126           if (option) {
01127             TString* tmp = par->format(sigDigit,(k==0)?option:sibOption.Data()) ;
01128             ofs << *tmp ;
01129             delete tmp ;
01130           } else {
01131             TString* tmp = par->format((k==0)?*formatCmd:sibFormatCmd) ;
01132             ofs << *tmp ;
01133             delete tmp ;
01134           }
01135         }
01136         if (!(j==ncol-1 && k==nlist-1)) {
01137           ofs << " & " ;
01138         }
01139       }
01140     }
01141     ofs << "\\\\" << endl ;
01142   }
01143   
01144   ofs << "\\end{tabular}" << endl ;
01145   listListRRV.Delete() ;
01146 }
01147 
01148 
01149 
01150 
01151 //_____________________________________________________________________________
01152 Bool_t RooAbsCollection::allInRange(const char* rangeSpec) const
01153 {
01154   // Return true if all contained object report to have their
01155   // value inside the specified range
01156 
01157   if (!rangeSpec) return kTRUE ;
01158 
01159   // Parse rangeSpec specification
01160   vector<string> cutVec ;
01161   if (rangeSpec && strlen(rangeSpec)>0) {
01162     if (strchr(rangeSpec,',')==0) {
01163       cutVec.push_back(rangeSpec) ;
01164     } else {
01165       char* buf = new char[strlen(rangeSpec)+1] ;
01166       strlcpy(buf,rangeSpec,strlen(rangeSpec)+1) ;
01167       const char* oneRange = strtok(buf,",") ;
01168       while(oneRange) {
01169         cutVec.push_back(oneRange) ;
01170         oneRange = strtok(0,",") ;
01171       }
01172       delete[] buf ;
01173     }
01174   }
01175 
01176 
01177   RooLinkedListIter iter = _list.iterator() ;
01178 
01179   // Apply range based selection criteria
01180   Bool_t selectByRange = kTRUE ;
01181   RooAbsArg* arg ;
01182   while((arg=(RooAbsArg*)iter.Next())) {
01183     Bool_t selectThisArg = kFALSE ;
01184     UInt_t icut ;
01185     for (icut=0 ; icut<cutVec.size() ; icut++) {
01186       if (arg->inRange(cutVec[icut].c_str())) {
01187         selectThisArg = kTRUE ;
01188         break ;
01189       }
01190     }
01191     if (!selectThisArg) {
01192       selectByRange = kFALSE ;
01193       break ;
01194     }
01195   }
01196 
01197   return selectByRange ;
01198 }
01199 
01200 
01201 
01202 

Generated on Tue Jul 5 15:05:25 2011 for ROOT_528-00b_version by  doxygen 1.5.1