#include "RooFit.h"
#include "Riostream.h"
#include "Riostream.h"
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include "TClass.h"
#include "TStopwatch.h"
#include "TRegexp.h"
#include "RooAbsCollection.h"
#include "RooStreamParser.h"
#include "RooFormula.h"
#include "RooAbsRealLValue.h"
#include "RooAbsCategoryLValue.h"
#include "RooStringVar.h"
#include "RooTrace.h"
#include "RooArgList.h"
#include "RooLinkedListIter.h"
#include "RooCmdConfig.h"
#include "RooRealVar.h"
#include "RooGlobalFunc.h"
#if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
char* operator+( streampos&, char* );
#endif
ClassImp(RooAbsCollection)
  ;
RooAbsCollection::RooAbsCollection() :
  _list(43),
  _ownCont(kFALSE), 
  _name()
{
  
  RooTrace::create(this) ;
}
RooAbsCollection::RooAbsCollection(const char *name) :
  _list(43),
  _ownCont(kFALSE), 
  _name(name)
{
  
  RooTrace::create(this) ;
}
RooAbsCollection::RooAbsCollection(const RooAbsCollection& other, const char *name) :
  TObject(other),
  RooPrintable(other),
  _list(other._list.getHashTableSize()) , 
  _ownCont(kFALSE), 
  _name(name)
{
  
  
  
  RooTrace::create(this) ;
  if (!name) setName(other.GetName()) ;
  
  
  TIterator *iterator= other.createIterator();
  RooAbsArg *arg = 0;
  while((arg= (RooAbsArg*)iterator->Next())) {
    add(*arg);
  }
  delete iterator;
}
RooAbsCollection::~RooAbsCollection() 
{
  
  
  if(_ownCont){ 
    safeDeleteList() ;
    
  }
  RooTrace::destroy(this) ;
}
void RooAbsCollection::safeDeleteList() 
{
  
  
  
  
  if (getSize()==1) {
    _list.Delete() ;
    return ;
  }
  
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  Bool_t working = kTRUE ;
  while(working) {
    working = kFALSE ;
    iter->Reset() ;
    while((arg=(RooAbsArg*)iter->Next())) {
      
      if (!arg->dependsOn(*this,arg)) {
	
	remove(*arg) ;
	delete arg ;
	working = kTRUE ;
      } 
    }
    if (_list.GetSize()<2) break ;
  }
  delete iter ;
  
  if (getSize()>1) {    
    cout << "RooAbsCollection::safeDeleteList(" << GetName() 
	 << ") WARNING: unable to delete following elements in client-server order " ;
    Print("1") ;
  }
  
  _list.Delete() ;
}
RooAbsCollection* RooAbsCollection::snapshot(Bool_t deepCopy) const
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  TString snapName("Snapshot of ") ;
  snapName.Append(GetName()) ;
  RooAbsCollection* snapshot = (RooAbsCollection*) create(snapName.Data()) ;
  snapshot->setHashTableSize(1000) ;
  
  TIterator *iterator= createIterator();
  RooAbsArg *orig = 0;
  while((0 != (orig= (RooAbsArg*)iterator->Next()))) {
    RooAbsArg *copy= (RooAbsArg*)orig->Clone();
    snapshot->add(*copy);
  }
  delete iterator;
  TIterator* vIter = snapshot->createIterator() ;
  RooAbsArg* var ;
  
  Bool_t error(kFALSE) ;
  if (deepCopy) {
    
    while ((var=(RooAbsArg*)vIter->Next())) {
      error |= snapshot->addServerClonesToList(*var) ;
    }
  }
  
  if (error) {
    cout << "RooAbsCollection::snapshot(): Errors occurred in deep clone process, snapshot not created" << endl ;
    snapshot->_ownCont = kTRUE ;    
    delete snapshot ;
    return 0 ;
  }
   
  vIter->Reset() ;
  while ((var=(RooAbsArg*)vIter->Next())) {
    var->redirectServers(*snapshot,deepCopy) ;
  }
  delete vIter ;
  
  snapshot->_ownCont = kTRUE ;
  return snapshot ;
}
Bool_t RooAbsCollection::addServerClonesToList(const RooAbsArg& var)
{
  
  Bool_t ret(kFALSE) ;
  TIterator* sIter = var.serverIterator() ;
  RooAbsArg* server ;
  while ((server=(RooAbsArg*)sIter->Next())) {
    RooAbsArg* tmp = find(server->GetName()) ;
    if (!tmp) {
      RooAbsArg* serverClone = (RooAbsArg*)server->Clone() ;      
      serverClone->setAttribute("SnapShot_ExtRefClone") ;
      _list.Add(serverClone) ;      
      ret |= addServerClonesToList(*server) ;
    } else {
    }
  }
  delete sIter ;
  return ret ;
}
RooAbsCollection &RooAbsCollection::operator=(const RooAbsCollection& other) {
  
  
  if (&other==this) return *this ;
  RooAbsArg *elem, *theirs ;
  RooLinkedListIter iter = _list.iterator() ;
  Int_t index(getSize());
  while(--index >= 0) {
    elem= (RooAbsArg*)_list.At(index);
    theirs= other.find(elem->GetName());
    if(!theirs) continue;
    theirs->syncCache() ;
    elem->copyCache(theirs) ;
  }
  return *this;
}
Bool_t RooAbsCollection::addOwned(RooAbsArg& var, Bool_t silent) {
  
  
  
  
  
  
  if(!_ownCont && (getSize() > 0) && !silent) {
    cout << ClassName() << "::" << GetName() << "::addOwned: can only add to an owned list" << endl;
    return kFALSE;
  }
  _ownCont= kTRUE;
  _list.Add((RooAbsArg*)&var);
  return kTRUE;
}
RooAbsArg *RooAbsCollection::addClone(const RooAbsArg& var, Bool_t silent) {
  
  
  
  
  
  
  if(!_ownCont && (getSize() > 0) && !silent) {
    cout << ClassName() << "::" << GetName() << "::addClone: can only add to an owned list" << endl;
    return 0;
  }
  _ownCont= kTRUE;
  
  RooAbsArg *clone= (RooAbsArg*)var.Clone();
  if(0 != clone) _list.Add((RooAbsArg*)clone);
  return clone;
}
Bool_t RooAbsCollection::add(const RooAbsArg& var, Bool_t silent) {
  
  
  
  
  if(_ownCont && !silent) {
    cout << ClassName() << "::" << GetName() << "::add: cannot add to an owned list" << endl;
    return kFALSE;
  }
  
  _list.Add((RooAbsArg*)&var);
  return kTRUE;
}
Bool_t RooAbsCollection::add(const RooAbsCollection& list, Bool_t silent)
{
  
  
  Bool_t result(false) ;
  Int_t n= list.getSize() ;
  for(Int_t index= 0; index < n; index++) {
    result |= add((RooAbsArg&)*list._list.At(index),silent) ;
  }
  return result;  
}
Bool_t RooAbsCollection::addOwned(const RooAbsCollection& list, Bool_t silent)
{
  
  
  Bool_t result(false) ;
  Int_t n= list.getSize() ;
  for(Int_t index= 0; index < n; index++) {
    result |= addOwned((RooAbsArg&)*list._list.At(index),silent) ;
  }
  return result;  
}
void RooAbsCollection::addClone(const RooAbsCollection& list, Bool_t silent)
{
  
  
  Int_t n= list.getSize() ;
  for(Int_t index= 0; index < n; index++) {
    addClone((RooAbsArg&)*list._list.At(index),silent) ;
  }
}
Bool_t RooAbsCollection::replace(const RooAbsCollection &other) {
  
  
  
  if(_ownCont) {
    cout << "RooAbsCollection: cannot replace variables in a copied list" << endl;
    return kFALSE;
  }
  
  TIterator *otherArgs= other.createIterator();
  const RooAbsArg *arg = 0;
  while((arg= (const RooAbsArg*)otherArgs->Next())) {
    
    RooAbsArg *found= find(arg->GetName());
    if(found) replace(*found,*arg);
  }
  delete otherArgs;
  return kTRUE;
}
Bool_t RooAbsCollection::replace(const RooAbsArg& var1, const RooAbsArg& var2) 
{
  
  
  
  
  
  if(_ownCont) {
    cout << "RooAbsCollection: cannot replace variables in a copied list" << endl;
    return kFALSE;
  }
  
  const char *name= var1.GetName();
  Bool_t foundVar1(kFALSE) ;
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (arg==&var1) foundVar1=kTRUE ;
  }
  delete iter ;
  if (!foundVar1) {
    cout << "RooAbsCollection: variable \"" << name << "\" is not in the list"
	 << " and cannot be replaced" << endl;
    return kFALSE;
  }
  RooAbsArg *other= find(name);
  
  if (dynamic_cast<RooArgSet*>(this)) {
    other= find(var2.GetName());
    if(other != 0 && other != &var1) {
      cout << "RooAbsCollection: cannot replace \"" << name
	   << "\" with already existing \"" << var2.GetName() << "\"" << endl;
      return kFALSE;
    }
  }
  
  _list.Replace(&var1,&var2) ;
  return kTRUE;
}
Bool_t RooAbsCollection::remove(const RooAbsArg& var, Bool_t , Bool_t matchByNameOnly) {
  
  
  
  
  
  TString name(var.GetName()) ;
  Bool_t anyFound(kFALSE) ;
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if ((&var)==arg) {
      _list.Remove(arg) ;
      anyFound=kTRUE ;
    } else if (matchByNameOnly) {
      if (!name.CompareTo(arg->GetName())) {
	_list.Remove(arg) ;
	anyFound=kTRUE ;
      }
    }
  }
  delete iter ;
  
  return anyFound ;
}
Bool_t RooAbsCollection::remove(const RooAbsCollection& list, Bool_t silent, Bool_t matchByNameOnly) {
  
  
  Bool_t result(false) ;
  Int_t n= list.getSize() ;
  for(Int_t index= 0; index < n; index++) {
    result |= remove((RooAbsArg&)*list._list.At(index),silent,matchByNameOnly) ;
  }
  return result;
}
void RooAbsCollection::removeAll() {
  
  
  
  if(_ownCont) {
    safeDeleteList() ;
    _ownCont= kFALSE;
  }
  else {
    _list.Clear();
  }
}
void RooAbsCollection::setAttribAll(const Text_t* name, Bool_t value) 
{
  
  
  TIterator* iter= createIterator() ;
  RooAbsArg* arg ;
  while ((arg=(RooAbsArg*)iter->Next())) {
    arg->setAttribute(name,value) ;
  }
  delete iter ;
}
RooAbsCollection* RooAbsCollection::selectByAttrib(const char* name, Bool_t value) const
{
  
  
  
  TString selName(GetName()) ;
  selName.Append("_selection") ;
  RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ;
  
  
  TIterator* iter= createIterator() ;
  RooAbsArg* arg ;
  while ((arg=(RooAbsArg*)iter->Next())) {
    if (arg->getAttribute(name)==value)
      sel->add(*arg) ;
  }
  delete iter ;
  return sel ;
}
RooAbsCollection* RooAbsCollection::selectCommon(const RooAbsCollection& refColl) const 
{
  
  
  
  
  TString selName(GetName()) ;
  selName.Append("_selection") ;
  RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ; 
  
  TIterator* iter= createIterator() ;
  RooAbsArg* arg ;
  while ((arg=(RooAbsArg*)iter->Next())) {
    if (refColl.find(arg->GetName()))
      sel->add(*arg) ;
  }
  delete iter ;
  return sel ;
}
RooAbsCollection* RooAbsCollection::selectByName(const char* nameList, Bool_t verbose) const 
{
  
  
  
  
  TString selName(GetName()) ;
  selName.Append("_selection") ;
  RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ; 
  
  TIterator* iter = createIterator() ;
  char* buf = new char[strlen(nameList)+1] ;
  strcpy(buf,nameList) ;
  char* wcExpr = strtok(buf,",") ;
  while(wcExpr) {
    TRegexp rexp(wcExpr,kTRUE) ;
    if (verbose) {
      cout << "RooAbsCollection::selectByName(" << GetName() << ") processing expression '" << wcExpr << "'" << endl ;
    }
    iter->Reset() ;
    RooAbsArg* arg ;
    while((arg=(RooAbsArg*)iter->Next())) {
      if (TString(arg->GetName()).Index(rexp)>=0) {
	if (verbose) {
	  cout << "RooAbsCollection::selectByName(" << GetName() << ") selected element " << arg->GetName() << endl ;
	}
	sel->add(*arg) ;
      }
    }
    wcExpr = strtok(0,",") ;
  }
  delete iter ;
  delete[] buf ;
  return sel ;
}
Bool_t RooAbsCollection::equals(const RooAbsCollection& otherColl) const
{
  
  
  if (getSize() != otherColl.getSize()) return kFALSE ;
  
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (!otherColl.find(arg->GetName())) {
      delete iter ;
      return kFALSE ;
    }
  }
  delete iter ;
  return kTRUE ;
}
Bool_t RooAbsCollection::overlaps(const RooAbsCollection& otherColl) const 
{
  
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (otherColl.find(arg->GetName())) {
      delete iter ;
      return kTRUE ;
    }
  }
  delete iter ;
  return kFALSE ;
}
RooAbsArg *RooAbsCollection::find(const char *name) const 
{
  
  
  return (RooAbsArg*) _list.find(name);
}
void RooAbsCollection::printToStream(ostream& os, PrintOption opt, TString indent) const {
  
  
  
  
  
  
  if (opt==OneLine || opt==InLine) {
    os << "(" ;
    TIterator *iter= createIterator();
    RooAbsArg *arg ;
    Bool_t first(kTRUE) ;
    while((arg=(RooAbsArg*)iter->Next())) {
      if (!first) {
	os << "," ;
      } else {
	first = kFALSE ;
      }
      os << arg->GetName() ;
    }
    os << ")" ;
    if (opt==OneLine) {
      os << endl ;
    }
    delete iter ;
    return ;
  }
  os << ClassName() << "::" << GetName() << ":" << (_ownCont?" (Owning contents)":"") << endl;
  if(opt >= Standard) {
    TIterator *iterator= createIterator();
    int index= 0;
    RooAbsArg *next = 0;
    opt= lessVerbose(opt);
    TString deeper(indent);
    deeper.Append("     ");
    
    Int_t maxNameLen(1) ;
    Int_t nameFieldLength = RooAbsArg::_nameLength ;
    if (nameFieldLength==0) {
      while((next=(RooAbsArg*)iterator->Next())) {
	Int_t len = strlen(next->GetName()) ;
	if (len>maxNameLen) maxNameLen = len ;
      }
      iterator->Reset() ;
      RooAbsArg::nameFieldLength(maxNameLen+1) ;
    }
    while((0 != (next= (RooAbsArg*)iterator->Next()))) {
      os << indent << setw(3) << ++index << ") ";
      next->printToStream(os,opt,deeper);
    }
    delete iterator;
    
    if (nameFieldLength==0) RooAbsArg::nameFieldLength(0) ;
  }
}
void RooAbsCollection::dump() const 
{
  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    cout << arg << " " << arg->IsA()->GetName() << "::" << arg->GetName() << " (" << arg->GetTitle() << ")" << endl ;
  }
  delete iter ;
}
void RooAbsCollection::printLatex(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
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  RooCmdConfig pc("RooAbsCollection::printLatex()") ;
  pc.defineInt("ncol","Columns",0,1) ;
  pc.defineString("outputFile","OutputFile",0,"") ;
  pc.defineString("format","Format",0,"NEYVU") ;
  pc.defineInt("sigDigit","Format",0,1) ;
  pc.defineObject("siblings","Sibling",0,0,kTRUE) ;
  pc.defineInt("dummy","FormatArgs",0,0) ;
  pc.defineMutex("Format","FormatArgs") ;
 
  
  RooLinkedList cmdList;
  cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
  
  pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
  if (!pc.ok(kTRUE)) {
    return ;
  }
  const char* outFile = pc.getString("outputFile") ;
  if (outFile && strlen(outFile)) {
    ofstream ofs(outFile) ;
    if (pc.hasProcessed("FormatArgs")) {
      RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
      formatCmd->addArg(RooFit::LatexTableStyle()) ;
      printLatex(ofs,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;    
    } else {
      printLatex(ofs,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
    }
  } else {
    if (pc.hasProcessed("FormatArgs")) {
      RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
      formatCmd->addArg(RooFit::LatexTableStyle()) ;
      printLatex(cout,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;    
    } else {
      printLatex(cout,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
    }
  }
}
void RooAbsCollection::printLatex(ostream& ofs, Int_t ncol, const char* option, Int_t sigDigit, const RooLinkedList& siblingList, const RooCmdArg* formatCmd) const 
{
  
  Int_t nrow = (Int_t) (getSize() / ncol + 0.99) ;
  Int_t i,j,k ;
  
  TString sibOption ;
  RooCmdArg sibFormatCmd ;
  if (option) {
    sibOption = option ;
    sibOption.ReplaceAll("N","") ;
    sibOption.ReplaceAll("n","") ;
  } else {
    sibFormatCmd = *formatCmd ;
    TString tmp = formatCmd->_s[0] ;
    tmp.ReplaceAll("N","") ;    
    tmp.ReplaceAll("n","") ;    
    static char buf[100] ;
    strcpy(buf,tmp.Data()) ;
    sibFormatCmd._s[0] = buf ;
  }
  
  RooLinkedList listList ;
  listList.Add((RooAbsArg*)this) ;
  TIterator* sIter = siblingList.MakeIterator() ;
  RooAbsCollection* col ;
  while((col=(RooAbsCollection*)sIter->Next())) {
    listList.Add(col) ;
  }
  delete sIter ;
  RooLinkedList listListRRV ;
  
  TIterator* lIter = listList.MakeIterator() ;
  RooArgList* prevList = 0 ;
  while((col=(RooAbsCollection*)lIter->Next())) {
    RooArgList* list = new RooArgList ;
    TIterator* iter = col->createIterator() ;
    RooAbsArg* arg ;
    while((arg=(RooAbsArg*)iter->Next())) {    
      
      RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
      if (rrv) {
	list->add(*rrv) ;
      } else {
	cout << "RooAbsCollection::printLatex: can only print RooRealVar in LateX, skipping non-RooRealVar object named "
	     << arg->GetName() << endl ;      
      }
      if (prevList && TString(rrv->GetName()).CompareTo(prevList->at(list->getSize()-1)->GetName())) {
	cout << "RooAbsCollection::printLatex: WARNING: naming and/or ordering of sibling list is different" << endl ;
      }
    }
    delete iter ;
    listListRRV.Add(list) ;
    if (prevList && list->getSize() != prevList->getSize()) {
      cout << "RooAbsCollection::printLatex: ERROR: sibling list(s) must have same length as self" << endl ;
      delete list ;
      listListRRV.Delete() ;
      return ;
    }
    prevList = list ;
  }
  
  Int_t nlist = listListRRV.GetSize() ;
  TString subheader = "l" ;
  for (k=0 ; k<nlist ; k++) subheader += "c" ;
  TString header = "\\begin{tabular}{" ;
  for (j=0 ; j<ncol ; j++) {
    if (j>0) header += "|" ;
    header += subheader ;
  }
  header += "}" ;
  ofs << header << endl ;
  
  for (i=0 ; i<nrow ; i++) {
    for (j=0 ; j<ncol ; j++) {
      for (k=0 ; k<nlist ; k++) {
	RooRealVar* par = (RooRealVar*) ((RooArgList*)listListRRV.At(k))->at(i+j*nrow) ;
	if (par) {
	  if (option) {
	    ofs << *par->format(sigDigit,(k==0)?option:sibOption.Data()) ;
	  } else {
	    ofs << *par->format((k==0)?*formatCmd:sibFormatCmd) ;
	  }
	}
	if (!(j==ncol-1 && k==nlist-1)) {
	  ofs << " & " ;
	}
      }
    }
    ofs << "\\\\" << endl ;
  }
  
  ofs << "\\end{tabular}" << endl ;
  listListRRV.Delete() ;
}
Bool_t RooAbsCollection::allInRange(const char* rangeSpec) const
{
  if (!rangeSpec) return kTRUE ;
  
  vector<string> cutVec ;
  if (rangeSpec && strlen(rangeSpec)>0) {
    if (strchr(rangeSpec,',')==0) {
      cutVec.push_back(rangeSpec) ;
    } else {
      char* buf = new char[strlen(rangeSpec)+1] ;
      strcpy(buf,rangeSpec) ;
      const char* oneRange = strtok(buf,",") ;
      while(oneRange) {
	cutVec.push_back(oneRange) ;
	oneRange = strtok(0,",") ;
      }
      delete[] buf ;
    }
  }
  RooLinkedListIter iter = _list.iterator() ;
  
  Bool_t selectByRange = kTRUE ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter.Next())) {
    Bool_t selectThisArg = kFALSE ;
    UInt_t icut ;
    for (icut=0 ; icut<cutVec.size() ; icut++) {
      if (arg->inRange(cutVec[icut].c_str())) {
	selectThisArg = kTRUE ;
	break ;
      }
    }
    if (!selectThisArg) {
      selectByRange = kFALSE ;
      break ;
    }
  }
  return selectByRange ;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.