Logo ROOT   6.12/07
Reference Guide
RooWorkspace.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * *
8  * Copyright (c) 2000-2005, Regents of the University of California *
9  * and Stanford University. All rights reserved. *
10  * *
11  * Redistribution and use in source and binary forms, *
12  * with or without modification, are permitted according to the terms *
13  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
14  *****************************************************************************/
15 
16 /**
17 \file RooWorkspace.cxx
18 \class RooWorkspace
19 \ingroup Roofitcore
20 
21 The RooWorkspace is a persistable container for RooFit projects. A workspace
22 can contain and own variables, p.d.f.s, functions and datasets. All objects
23 that live in the workspace are owned by the workspace. The import() method
24 enforces consistency of objects upon insertion into the workspace (e.g. no
25 duplicate object with the same name are allowed) and makes sure all objects
26 in the workspace are connected to each other. Easy accessor methods like
27 pdf(), var() and data() allow to refer to the contents of the workspace by
28 object name. The entire RooWorkspace can be saved into a ROOT TFile and organises
29 the consistent streaming of its contents without duplication.
30 If a RooWorkspace contains custom classes, i.e. classes not in the
31 ROOT distribution, portability of workspaces can be enhanced by
32 storing the source code of those classes in the workspace as well.
33 This process is also organized by the workspace through the
34 importClassCode() method.
35 **/
36 
37 #include "RooFit.h"
38 #include "RooWorkspace.h"
39 #include "RooAbsPdf.h"
40 #include "RooRealVar.h"
41 #include "RooCategory.h"
42 #include "RooAbsData.h"
43 #include "RooCmdConfig.h"
44 #include "RooMsgService.h"
45 #include "RooConstVar.h"
46 #include "RooResolutionModel.h"
47 #include "RooPlot.h"
48 #include "RooRandom.h"
49 #include "TInterpreter.h"
50 #include "TClassTable.h"
51 #include "TBaseClass.h"
52 #include "TSystem.h"
53 #include "TRegexp.h"
54 #include "RooFactoryWSTool.h"
55 #include "RooAbsStudy.h"
56 #include "RooTObjWrap.h"
57 #include "RooAbsOptTestStatistic.h"
58 #include "TROOT.h"
59 #include "TFile.h"
60 #include "TH1.h"
61 #include <map>
62 #include <string>
63 #include <list>
64 #include <set>
65 
66 using namespace std ;
67 
68 
69 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,19,02)
70 #include "Api.h"
71 #endif
72 
73 
74 #include "TClass.h"
75 #include "Riostream.h"
76 #include <string.h>
77 #include <assert.h>
78 
80 ;
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 
85 ;
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 
90 ;
91 
94 string RooWorkspace::_classFileExportDir = ".wscode.%s.%s" ;
96 
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Add 'dir' to search path for class declaration (header) files, when
100 /// attempting to import class code with importClassClode()
101 
103 {
104  _classDeclDirList.push_back(dir) ;
105 }
106 
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Add 'dir' to search path for class implementation (.cxx) files, when
110 /// attempting to import class code with importClassClode()
111 
113 {
114  _classImplDirList.push_back(dir) ;
115 }
116 
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Specify the name of the directory in which embedded source
120 /// code is unpacked and compiled. The specified string may contain
121 /// one '%s' token which will be substituted by the workspace name
122 
124 {
125  if (dir) {
126  _classFileExportDir = dir ;
127  } else {
128  _classFileExportDir = ".wscode.%s.%s" ;
129  }
130 }
131 
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 /// If flag is true, source code of classes not the the ROOT distribution
135 /// is automatically imported if on object of such a class is imported
136 /// in the workspace
137 
139 {
140  _autoClass = flag ;
141 }
142 
143 
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Default constructor
147 
148 RooWorkspace::RooWorkspace() : _classes(this), _dir(0), _factory(0), _doExport(kFALSE), _openTrans(kFALSE)
149 {
150 }
151 
152 
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Construct empty workspace with given name and title
156 
157 RooWorkspace::RooWorkspace(const char* name, const char* title) :
158  TNamed(name,title?title:name), _classes(this), _dir(0), _factory(0), _doExport(kFALSE), _openTrans(kFALSE)
159 {
160 }
161 
162 
163 RooWorkspace::RooWorkspace(const char* name, Bool_t doCINTExport) :
164  TNamed(name,name), _classes(this), _dir(0), _factory(0), _doExport(kFALSE), _openTrans(kFALSE)
165 {
166  // Construct empty workspace with given name and option to export reference to all workspace contents to a CINT namespace with the same name
167  if (doCINTExport) {
168  exportToCint(name) ;
169  }
170 }
171 
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Workspace copy constructor
175 
177  TNamed(other), _uuid(other._uuid), _classes(other._classes,this), _dir(0), _factory(0), _doExport(kFALSE), _openTrans(kFALSE)
178 {
179  // Copy owned nodes
181 
182  // Copy datasets
183  TIterator* iter = other._dataList.MakeIterator() ;
184  TObject* data2 ;
185  while((data2=iter->Next())) {
186  _dataList.Add(data2->Clone()) ;
187  }
188  delete iter ;
189 
190  // Copy snapshots
191  TIterator* iter2 = other._snapshots.MakeIterator() ;
192  RooArgSet* snap ;
193  while((snap=(RooArgSet*)iter2->Next())) {
194  RooArgSet* snapClone = (RooArgSet*) snap->snapshot() ;
195  snapClone->setName(snap->GetName()) ;
196  _snapshots.Add(snapClone) ;
197  }
198  delete iter2 ;
199 
200  // Copy named sets
201  for (map<string,RooArgSet>::const_iterator iter3 = other._namedSets.begin() ; iter3 != other._namedSets.end() ; ++iter3) {
202  // Make RooArgSet with equivalent content of this workspace
203  RooArgSet* tmp = (RooArgSet*) _allOwnedNodes.selectCommon(iter3->second) ;
204  _namedSets[iter3->first].add(*tmp) ;
205  delete tmp ;
206  }
207 
208  // Copy generic objects
209  TIterator* iter4 = other._genObjects.MakeIterator() ;
210  TObject* gobj ;
211  while((gobj=iter4->Next())) {
212  _genObjects.Add(gobj->Clone()) ;
213  }
214  delete iter4 ;
215 
216 }
217 
218 
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Workspace destructor
222 
224 {
225  // Delete references to variables that were declared in CINT
226  if (_doExport) {
227  unExport() ;
228  }
229 
230  // Delete contents
231  _dataList.Delete() ;
232  if (_dir) {
233  delete _dir ;
234  }
235  _snapshots.Delete() ;
236 
237  // WVE named sets too?
238 
239  _genObjects.Delete() ;
240 }
241 
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Import a RooAbsArg or RooAbsData set from a workspace in a file. Filespec should be constructed as "filename:wspacename:objectname"
245 /// The arguments will be passed on to the relevant RooAbsArg& or RooAbsData& import call
246 
247 Bool_t RooWorkspace::import(const char* fileSpec,
248  const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
249  const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6,
250  const RooCmdArg& arg7, const RooCmdArg& arg8, const RooCmdArg& arg9)
251 {
252  // Parse file/workspace/objectname specification
253  char buf[64000];
254  strlcpy(buf, fileSpec, 64000);
255  char* filename = strtok(buf,":") ;
256  char* wsname = strtok(0,":") ;
257  char* objname = strtok(0,":") ;
258 
259  // Check that parsing was successful
260  if (!filename||!wsname||!objname) {
261  coutE(InputArguments) << "RooWorkspace(" << GetName() << ") ERROR in file specification, expecting for 'filename:wsname:objname'" << endl ;
262  return kTRUE ;
263  }
264 
265  // Check that file can be opened
266  TFile* f = TFile::Open(filename) ;
267  if (f==0) {
268  coutE(InputArguments) << "RooWorkspace(" << GetName() << ") ERROR opening file " << filename << endl ;
269  return 0 ;
270  }
271 
272  // That that file contains workspace
273  RooWorkspace* w = dynamic_cast<RooWorkspace*>(f->Get(wsname)) ;
274  if (w==0) {
275  coutE(InputArguments) << "RooWorkspace(" << GetName() << ") ERROR: No object named " << wsname << " in file " << filename
276  << " or object is not a RooWorkspace" << endl ;
277  return 0 ;
278  }
279 
280  // Check that workspace contains object and forward to appropriate import method
281  RooAbsArg* warg = w->arg(objname) ;
282  if (warg) {
283  Bool_t ret = import(*warg,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) ;
284  delete f ;
285  return ret ;
286  }
287  RooAbsData* wdata = w->data(objname) ;
288  if (wdata) {
289  Bool_t ret = import(*wdata,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) ;
290  delete f ;
291  return ret ;
292  }
293 
294  coutE(InputArguments) << "RooWorkspace(" << GetName() << ") ERROR: No RooAbsArg or RooAbsData object named " << objname
295  << " in workspace " << wsname << " in file " << filename << endl ;
296  return kTRUE ;
297 }
298 
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Import multiple RooAbsArg objects into workspace. For details on arguments see documentation
302 /// of import() method for single RooAbsArg
303 
305  const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
306  const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6,
307  const RooCmdArg& arg7, const RooCmdArg& arg8, const RooCmdArg& arg9)
308 {
309  TIterator* iter = args.createIterator() ;
310  RooAbsArg* oneArg ;
311  Bool_t ret(kFALSE) ;
312  while((oneArg=(RooAbsArg*)iter->Next())) {
313  ret |= import(*oneArg,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) ;
314  }
315  return ret ;
316 }
317 
318 
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Import a RooAbsArg object, e.g. function, p.d.f or variable into the workspace. This import function clones the input argument and will
322 /// own the clone. If a composite object is offered for import, e.g. a p.d.f with parameters and observables, the
323 /// complete tree of objects is imported. If any of the _variables_ of a composite object (parameters/observables) are already
324 /// in the workspace the imported p.d.f. is connected to the already existing variables. If any of the _function_ objects (p.d.f, formulas)
325 /// to be imported already exists in the workspace an error message is printed and the import of the entire tree of objects is cancelled.
326 /// Several optional arguments can be provided to modify the import procedure.
327 ///
328 /// Accepted arguments
329 /// -------------------------------
330 /// RenameConflictNodes(const char* suffix) -- Add suffix to branch node name if name conflicts with existing node in workspace
331 /// RenameAllNodes(const char* suffix) -- Add suffix to all branch node names including top level node
332 /// RenameAllVariables(const char* suffix) -- Add suffix to all variables names
333 /// RenameAllVariablesExcept(const char* suffix, const char* exceptionList) -- Add suffix to all variables names, except ones listed
334 /// RenameVariable(const char* inputName, const char* outputName) -- Rename variable as specified upon import.
335 /// RecycleConflictNodes() -- If any of the function objects to be imported already exist in the name space, connect the
336 /// imported expression to the already existing nodes. WARNING: use with care! If function definitions
337 /// do not match, this alters the definition of your function upon import
338 /// Silence() -- Do not issue any info message
339 ///
340 /// The RenameConflictNodes, RenameNodes and RecycleConflictNodes arguments are mutually exclusive. The RenameVariable argument can be repeated
341 /// as often as necessary to rename multiple variables. Alternatively, a single RenameVariable argument can be given with
342 /// two comma separated lists.
343 
345  const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
346  const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6,
347  const RooCmdArg& arg7, const RooCmdArg& arg8, const RooCmdArg& arg9)
348 {
349  RooLinkedList args ;
350  args.Add((TObject*)&arg1) ;
351  args.Add((TObject*)&arg2) ;
352  args.Add((TObject*)&arg3) ;
353  args.Add((TObject*)&arg4) ;
354  args.Add((TObject*)&arg5) ;
355  args.Add((TObject*)&arg6) ;
356  args.Add((TObject*)&arg7) ;
357  args.Add((TObject*)&arg8) ;
358  args.Add((TObject*)&arg9) ;
359 
360  // Select the pdf-specific commands
361  RooCmdConfig pc(Form("RooWorkspace::import(%s)",GetName())) ;
362 
363  pc.defineString("conflictSuffix","RenameConflictNodes",0) ;
364  pc.defineInt("renameConflictOrig","RenameConflictNodes",0,0) ;
365  pc.defineString("allSuffix","RenameAllNodes",0) ;
366  pc.defineString("allVarsSuffix","RenameAllVariables",0) ;
367  pc.defineString("allVarsExcept","RenameAllVariables",1) ;
368  pc.defineString("varChangeIn","RenameVar",0,"",kTRUE) ;
369  pc.defineString("varChangeOut","RenameVar",1,"",kTRUE) ;
370  pc.defineString("factoryTag","FactoryTag",0) ;
371  pc.defineInt("useExistingNodes","RecycleConflictNodes",0,0) ;
372  pc.defineInt("silence","Silence",0,0) ;
373  pc.defineInt("noRecursion","NoRecursion",0,0) ;
374  pc.defineMutex("RenameConflictNodes","RenameAllNodes") ;
375  pc.defineMutex("RenameConflictNodes","RecycleConflictNodes") ;
376  pc.defineMutex("RenameAllNodes","RecycleConflictNodes") ;
377  pc.defineMutex("RenameVariable","RenameAllVariables") ;
378 
379  // Process and check varargs
380  pc.process(args) ;
381  if (!pc.ok(kTRUE)) {
382  return kTRUE ;
383  }
384 
385  // Decode renaming logic into suffix string and boolean for conflictOnly mode
386  const char* suffixC = pc.getString("conflictSuffix") ;
387  const char* suffixA = pc.getString("allSuffix") ;
388  const char* suffixV = pc.getString("allVarsSuffix") ;
389  const char* exceptVars = pc.getString("allVarsExcept") ;
390  const char* varChangeIn = pc.getString("varChangeIn") ;
391  const char* varChangeOut = pc.getString("varChangeOut") ;
392  Bool_t renameConflictOrig = pc.getInt("renameConflictOrig") ;
393  Int_t useExistingNodes = pc.getInt("useExistingNodes") ;
394  Int_t silence = pc.getInt("silence") ;
395  Int_t noRecursion = pc.getInt("noRecursion") ;
396 
397 
398  // Turn zero length strings into null pointers
399  if (suffixC && strlen(suffixC)==0) suffixC = 0 ;
400  if (suffixA && strlen(suffixA)==0) suffixA = 0 ;
401 
402  Bool_t conflictOnly = suffixA ? kFALSE : kTRUE ;
403  const char* suffix = suffixA ? suffixA : suffixC ;
404 
405  // Process any change in variable names
406  map<string,string> varMap ;
407  if (strlen(varChangeIn)>0) {
408 
409  // Parse comma separated lists into map<string,string>
410  char tmp[64000];
411  strlcpy(tmp, varChangeIn, 64000);
412  list<string> tmpIn,tmpOut ;
413  char* ptr = strtok(tmp,", ") ;
414  while (ptr) {
415  tmpIn.push_back(ptr) ;
416  ptr = strtok(0,", ") ;
417  }
418  strlcpy(tmp, varChangeOut, 64000);
419  ptr = strtok(tmp,", ") ;
420  while (ptr) {
421  tmpOut.push_back(ptr) ;
422  ptr = strtok(0,", ") ;
423  }
424  list<string>::iterator iin = tmpIn.begin() ;
425  list<string>::iterator iout = tmpOut.begin() ;
426  for (;iin!=tmpIn.end() ; ++iin,++iout) {
427  varMap[*iin]=*iout ;
428  }
429  }
430 
431  // Process RenameAllVariables argument if specified
432  // First convert exception list if provided
433  std::set<string> exceptVarNames ;
434  char tmp[64000];
435  if (exceptVars && strlen(exceptVars)) {
436  strlcpy(tmp, exceptVars, 64000);
437  char *ptr = strtok(tmp, ", ");
438  while (ptr) {
439  exceptVarNames.insert(ptr);
440  ptr = strtok(0, ", ");
441  }
442  }
443 
444  if (suffixV != 0 && strlen(suffixV)>0) {
445  RooArgSet* vars = inArg.getVariables() ;
446  TIterator* iter = vars->createIterator() ;
447  RooAbsArg* v ;
448  while((v=(RooAbsArg*)iter->Next())) {
449  if (exceptVarNames.find(v->GetName())==exceptVarNames.end()) {
450  varMap[v->GetName()] = Form("%s_%s",v->GetName(),suffixV) ;
451  }
452  }
453  delete iter ;
454  delete vars ;
455  }
456 
457  // Scan for overlaps with current contents
458  RooAbsArg* wsarg = _allOwnedNodes.find(inArg.GetName()) ;
459 
460  // Check for factory specification match
461  const char* tagIn = inArg.getStringAttribute("factory_tag") ;
462  const char* tagWs = wsarg ? wsarg->getStringAttribute("factory_tag") : 0 ;
463  Bool_t factoryMatch = (tagIn && tagWs && !strcmp(tagIn,tagWs)) ;
464  if (factoryMatch) {
465  ((RooAbsArg&)inArg).setAttribute("RooWorkspace::Recycle") ;
466  }
467 
468  if (!suffix && wsarg && !useExistingNodes && !(inArg.isFundamental() && varMap[inArg.GetName()]!="")) {
469  if (!factoryMatch) {
470  if (wsarg!=&inArg) {
471  coutE(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") ERROR importing object named " << inArg.GetName()
472  << ": another instance with same name already in the workspace and no conflict resolution protocol specified" << endl ;
473  return kTRUE ;
474  } else {
475  if (!silence) {
476  coutI(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") Object " << inArg.GetName() << " is already in workspace!" << endl ;
477  }
478  return kTRUE ;
479  }
480  } else {
481  coutI(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") Recycling existing object " << inArg.GetName() << " created with identical factory specification" << endl ;
482  }
483  }
484 
485  // Make list of conflicting nodes
486  RooArgSet conflictNodes ;
487  RooArgSet branchSet ;
488  if (noRecursion) {
489  branchSet.add(inArg) ;
490  } else {
491  inArg.branchNodeServerList(&branchSet) ;
492  }
493  TIterator* iter = branchSet.createIterator() ;
494  RooAbsArg* branch ;
495  while ((branch=(RooAbsArg*)iter->Next())) {
496  RooAbsArg* wsbranch = _allOwnedNodes.find(branch->GetName()) ;
497  if (wsbranch && wsbranch!=branch && !branch->getAttribute("RooWorkspace::Recycle") && !useExistingNodes) {
498  conflictNodes.add(*branch) ;
499  }
500  }
501  delete iter ;
502 
503  // Terminate here if there are conflicts and no resolution protocol
504  if (conflictNodes.getSize()>0 && !suffix && !useExistingNodes) {
505  coutE(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") ERROR object named " << inArg.GetName() << ": component(s) "
506  << conflictNodes << " already in the workspace and no conflict resolution protocol specified" << endl ;
507  return kTRUE ;
508  }
509 
510  // Now create a working copy of the incoming object tree
511  RooArgSet* cloneSet = (RooArgSet*) RooArgSet(inArg).snapshot(noRecursion==kFALSE) ;
512  RooAbsArg* cloneTop = cloneSet->find(inArg.GetName()) ;
513 
514  // Mark all nodes for renaming if we are not in conflictOnly mode
515  if (!conflictOnly) {
516  conflictNodes.removeAll() ;
517  conflictNodes.add(branchSet) ;
518  }
519 
520  // Mark nodes that are to be renamed with special attribute
521  string topName2 = cloneTop->GetName() ;
522  if (!renameConflictOrig) {
523  // Mark all nodes to be imported for renaming following conflict resolution protocol
524  TIterator* citer = conflictNodes.createIterator() ;
525  RooAbsArg* cnode ;
526  while ((cnode=(RooAbsArg*)citer->Next())) {
527  RooAbsArg* cnode2 = cloneSet->find(cnode->GetName()) ;
528  string origName = cnode2->GetName() ;
529  cnode2->SetName(Form("%s_%s",cnode2->GetName(),suffix)) ;
530  cnode2->SetTitle(Form("%s (%s)",cnode2->GetTitle(),suffix)) ;
531  string tag = Form("ORIGNAME:%s",origName.c_str()) ;
532  cnode2->setAttribute(tag.c_str()) ;
533  if (!cnode2->getStringAttribute("origName")) {
534  string tag2 = Form("%s",origName.c_str()) ;
535  cnode2->setStringAttribute("origName",tag2.c_str()) ;
536  }
537 
538  // Save name of new top level node for later use
539  if (cnode2==cloneTop) {
540  topName2 = cnode2->GetName() ;
541  }
542 
543  if (!silence) {
544  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName()
545  << ") Resolving name conflict in workspace by changing name of imported node "
546  << origName << " to " << cnode2->GetName() << endl ;
547  }
548  }
549  delete citer ;
550  } else {
551 
552  // Rename all nodes already in the workspace to 'clear the way' for the imported nodes
553  TIterator* citer = conflictNodes.createIterator() ;
554  RooAbsArg* cnode ;
555  while ((cnode=(RooAbsArg*)citer->Next())) {
556 
557  string origName = cnode->GetName() ;
558  RooAbsArg* wsnode = _allOwnedNodes.find(origName.c_str()) ;
559  if (wsnode) {
560 
561  if (!wsnode->getStringAttribute("origName")) {
562  wsnode->setStringAttribute("origName",wsnode->GetName()) ;
563  }
564 
565  if (!_allOwnedNodes.find(Form("%s_%s",cnode->GetName(),suffix))) {
566  wsnode->SetName(Form("%s_%s",cnode->GetName(),suffix)) ;
567  wsnode->SetTitle(Form("%s (%s)",cnode->GetTitle(),suffix)) ;
568  } else {
569  // Name with suffix already taken, add additional suffix
570  Int_t n=1 ;
571  while (true) {
572  string newname = Form("%s_%s_%d",cnode->GetName(),suffix,n) ;
573  if (!_allOwnedNodes.find(newname.c_str())) {
574  wsnode->SetName(newname.c_str()) ;
575  wsnode->SetTitle(Form("%s (%s %d)",cnode->GetTitle(),suffix,n)) ;
576  break ;
577  }
578  n++ ;
579  }
580  }
581  if (!silence) {
582  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName()
583  << ") Resolving name conflict in workspace by changing name of original node "
584  << origName << " to " << wsnode->GetName() << endl ;
585  }
586  } else {
587  coutW(ObjectHandling) << "RooWorkspce::import(" << GetName() << ") Internal error: expected to find existing node "
588  << origName << " to be renamed, but didn't find it..." << endl ;
589  }
590 
591  }
592  delete citer ;
593 
594  }
595 
596  // Process any change in variable names
597  if (strlen(varChangeIn)>0 || (suffixV && strlen(suffixV)>0)) {
598 
599  // Process all changes in variable names
600  TIterator* cliter = cloneSet->createIterator() ;
601  RooAbsArg* cnode ;
602  while ((cnode=(RooAbsArg*)cliter->Next())) {
603 
604  if (varMap.find(cnode->GetName())!=varMap.end()) {
605  string origName = cnode->GetName() ;
606  cnode->SetName(varMap[cnode->GetName()].c_str()) ;
607  string tag = Form("ORIGNAME:%s",origName.c_str()) ;
608  cnode->setAttribute(tag.c_str()) ;
609  if (!cnode->getStringAttribute("origName")) {
610  string tag2 = Form("%s",origName.c_str()) ;
611  cnode->setStringAttribute("origName",tag2.c_str()) ;
612  }
613 
614  if (!silence) {
615  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") Changing name of variable "
616  << origName << " to " << cnode->GetName() << " on request" << endl ;
617  }
618 
619  if (cnode==cloneTop) {
620  topName2 = cnode->GetName() ;
621  }
622 
623  }
624  }
625  delete cliter ;
626  }
627 
628  // Now clone again with renaming effective
629  RooArgSet* cloneSet2 = (RooArgSet*) RooArgSet(*cloneTop).snapshot(noRecursion==kFALSE) ;
630  RooAbsArg* cloneTop2 = cloneSet2->find(topName2.c_str()) ;
631 
632  // Make final check list of conflicting nodes
633  RooArgSet conflictNodes2 ;
634  RooArgSet branchSet2 ;
635  //inArg.branchNodeServerList(&branchSet) ; // WVE not needed
636  TIterator* iter2 = branchSet2.createIterator() ;
637  RooAbsArg* branch2 ;
638  while ((branch2=(RooAbsArg*)iter2->Next())) {
639  if (_allOwnedNodes.find(branch2->GetName())) {
640  conflictNodes2.add(*branch2) ;
641  }
642  }
643  delete iter2 ;
644 
645  // Terminate here if there are conflicts and no resolution protocol
646  if (conflictNodes2.getSize()) {
647  coutE(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") ERROR object named " << inArg.GetName() << ": component(s) "
648  << conflictNodes2 << " cause naming conflict after conflict resolution protocol was executed" << endl ;
649  return kTRUE ;
650  }
651 
652  // Print a message for each imported node
653  iter = cloneSet2->createIterator() ;
654 
655  // Perform any auxiliary imports at this point
656  RooAbsArg* node ;
657  while((node=(RooAbsArg*)iter->Next())) {
658  if (node->importWorkspaceHook(*this)) {
659  coutE(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") ERROR object named " << node->GetName()
660  << " has an error in importing in one or more of its auxiliary objects, aborting" << endl ;
661  return kTRUE ;
662  }
663  }
664  iter->Reset() ;
665 
666  if (cloneSet2->getSize()+_allOwnedNodes.getSize() > 999) _allOwnedNodes.setHashTableSize(1000);
667 
668  RooArgSet recycledNodes ;
669  RooArgSet nodesToBeDeleted ;
670  while((node=(RooAbsArg*)iter->Next())) {
671 
672  if (_autoClass) {
673  if (!_classes.autoImportClass(node->IsA())) {
674  coutW(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") WARNING: problems import class code of object "
675  << node->IsA()->GetName() << "::" << node->GetName() << ", reading of workspace will require external definition of class" << endl ;
676  }
677  }
678 
679  // Point expensiveObjectCache to copy in this workspace
680  RooExpensiveObjectCache& oldCache = node->expensiveObjectCache() ;
682  _eocache.importCacheObjects(oldCache,node->GetName(),kTRUE) ;
683 
684  // Check if node is already in workspace (can only happen for variables or identical instances, unless RecycleConflictNodes is specified)
685  RooAbsArg* wsnode = _allOwnedNodes.find(node->GetName()) ;
686 
687  if (wsnode) {
688  // Do not import node, add not to list of nodes that require reconnection
689  if (!silence && useExistingNodes) {
690  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") using existing copy of " << node->IsA()->GetName()
691  << "::" << node->GetName() << " for import of " << cloneTop2->IsA()->GetName() << "::"
692  << cloneTop2->GetName() << endl ;
693  }
694  recycledNodes.add(*_allOwnedNodes.find(node->GetName())) ;
695 
696  // Delete clone of incoming node
697  nodesToBeDeleted.addOwned(*node) ;
698 
699  //cout << "WV: recycling existing node " << existingNode << " = " << existingNode->GetName() << " for imported node " << node << endl ;
700 
701  } else {
702  // Import node
703  if (!silence) {
704  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") importing " << node->IsA()->GetName() << "::"
705  << node->GetName() << endl ;
706  }
707  _allOwnedNodes.addOwned(*node) ;
708  if (_openTrans) {
709  _sandboxNodes.add(*node) ;
710  } else {
711  if (_dir && node->IsA() != RooConstVar::Class()) {
712  _dir->InternalAppend(node) ;
713  }
714  if (_doExport && node->IsA() != RooConstVar::Class()) {
715  exportObj(node) ;
716  }
717  }
718  }
719  }
720 
721  // Release working copy
722  // no need to do a safe list since it was generated from a snapshot
723  // just take ownership and delte elements by hand
724  cloneSet->releaseOwnership() ;
725  RooFIter cloneSet_iter = cloneSet->fwdIterator() ;
726  RooAbsArg* cloneNode ;
727  while ((cloneNode=(RooAbsArg*)cloneSet_iter.next())) {
728  delete cloneNode;
729  }
730  delete cloneSet ;
731 
732  // Reconnect any nodes that need to be
733  if (recycledNodes.getSize()>0) {
734  iter->Reset() ;
735  while((node=(RooAbsArg*)iter->Next())) {
736  node->redirectServers(recycledNodes) ;
737  }
738  }
739  delete iter ;
740 
741  cloneSet2->releaseOwnership() ;
742  delete cloneSet2 ;
743 
744  return kFALSE ;
745 }
746 
747 
748 
749 ////////////////////////////////////////////////////////////////////////////////
750 
752  const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
753  const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6,
754  const RooCmdArg& arg7, const RooCmdArg& arg8, const RooCmdArg& arg9)
755 
756 {
757  // Import a dataset (RooDataSet or RooDataHist) into the work space. The workspace will contain a copy of the data
758  // The dataset and its variables can be renamed upon insertion with the options below
759  //
760  // Accepted arguments
761  // -------------------------------
762  // Rename(const char* suffix) -- Rename dataset upon insertion
763  // RenameVariable(const char* inputName, const char* outputName) -- Change names of observables in dataset upon insertion
764 
765  coutI(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") importing dataset " << inData.GetName() << endl ;
766 
767  RooLinkedList args ;
768  args.Add((TObject*)&arg1) ;
769  args.Add((TObject*)&arg2) ;
770  args.Add((TObject*)&arg3) ;
771  args.Add((TObject*)&arg4) ;
772  args.Add((TObject*)&arg5) ;
773  args.Add((TObject*)&arg6) ;
774  args.Add((TObject*)&arg7) ;
775  args.Add((TObject*)&arg8) ;
776  args.Add((TObject*)&arg9) ;
777 
778  // Select the pdf-specific commands
779  RooCmdConfig pc(Form("RooWorkspace::import(%s)",GetName())) ;
780 
781  pc.defineString("dsetName","Rename",0,"") ;
782  pc.defineString("varChangeIn","RenameVar",0,"",kTRUE) ;
783  pc.defineString("varChangeOut","RenameVar",1,"",kTRUE) ;
784  pc.defineInt("embedded","Embedded",0,0) ;
785 
786  // Process and check varargs
787  pc.process(args) ;
788  if (!pc.ok(kTRUE)) {
789  return kTRUE ;
790  }
791 
792  // Decode renaming logic into suffix string and boolean for conflictOnly mode
793  const char* dsetName = pc.getString("dsetName") ;
794  const char* varChangeIn = pc.getString("varChangeIn") ;
795  const char* varChangeOut = pc.getString("varChangeOut") ;
796  Bool_t embedded = pc.getInt("embedded") ;
797 
798  // Transform emtpy string into null pointer
799  if (dsetName && strlen(dsetName)==0) {
800  dsetName=0 ;
801  }
802 
803  RooLinkedList& dataList = embedded ? _embeddedDataList : _dataList ;
804 
805  // Check that no dataset with target name already exists
806  if (dsetName && dataList.FindObject(dsetName)) {
807  coutE(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") ERROR dataset with name " << dsetName << " already exists in workspace, import aborted" << endl ;
808  return kTRUE ;
809  }
810  if (!dsetName && dataList.FindObject(inData.GetName())) {
811  coutE(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") ERROR dataset with name " << inData.GetName() << " already exists in workspace, import aborted" << endl ;
812  return kTRUE ;
813  }
814 
815  // Rename dataset if required
816  RooAbsData* clone ;
817  if (dsetName) {
818  coutI(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") changing name of dataset from " << inData.GetName() << " to " << dsetName << endl ;
819  clone = (RooAbsData*) inData.Clone(dsetName) ;
820  } else {
821  clone = (RooAbsData*) inData.Clone(inData.GetName()) ;
822  }
823 
824 
825  // Process any change in variable names
826  if (strlen(varChangeIn)>0) {
827 
828  // Parse comma separated lists of variable name changes
829  char tmp[64000];
830  strlcpy(tmp, varChangeIn, 64000);
831  list<string> tmpIn,tmpOut ;
832  char* ptr = strtok(tmp,",") ;
833  while (ptr) {
834  tmpIn.push_back(ptr) ;
835  ptr = strtok(0,",") ;
836  }
837  strlcpy(tmp, varChangeOut, 64000);
838  ptr = strtok(tmp,",") ;
839  while (ptr) {
840  tmpOut.push_back(ptr) ;
841  ptr = strtok(0,",") ;
842  }
843  list<string>::iterator iin = tmpIn.begin() ;
844  list<string>::iterator iout = tmpOut.begin() ;
845 
846  for (; iin!=tmpIn.end() ; ++iin,++iout) {
847  coutI(ObjectHandling) << "RooWorkSpace::import(" << GetName() << ") changing name of dataset observable " << *iin << " to " << *iout << endl ;
848  clone->changeObservableName(iin->c_str(),iout->c_str()) ;
849  }
850  }
851 
852  // Now import the dataset observables, unless dataset is embedded
853  RooAbsArg* carg ;
854  if (!embedded) {
855  TIterator* iter = clone->get()->createIterator() ;
856  while((carg=(RooAbsArg*)iter->Next())) {
857  if (!arg(carg->GetName())) {
858  import(*carg) ;
859  }
860  }
861  delete iter ;
862  }
863 
864  dataList.Add(clone) ;
865  if (_dir) {
866  _dir->InternalAppend(clone) ;
867  }
868  if (_doExport) {
869  exportObj(clone) ;
870  }
871 
872  // Set expensive object cache of dataset internal buffers to that of workspace
873  RooFIter iter2 = clone->get()->fwdIterator() ;
874  while ((carg=iter2.next())) {
876  }
877 
878 
879  return kFALSE ;
880 }
881 
882 
883 
884 
885 ////////////////////////////////////////////////////////////////////////////////
886 /// Define a named RooArgSet with given constituents. If importMissing is true, any constituents
887 /// of aset that are not in the workspace will be imported, otherwise an error is returned
888 /// for missing components
889 
890 Bool_t RooWorkspace::defineSet(const char* name, const RooArgSet& aset, Bool_t importMissing)
891 {
892  // Check if set was previously defined, if so print warning
893  map<string,RooArgSet>::iterator i = _namedSets.find(name) ;
894  if (i!=_namedSets.end()) {
895  coutW(InputArguments) << "RooWorkspace::defineSet(" << GetName() << ") WARNING redefining previously defined named set " << name << endl ;
896  }
897 
898  RooArgSet wsargs ;
899 
900  // Check all constituents of provided set
901  TIterator* iter = aset.createIterator() ;
902  RooAbsArg* sarg ;
903  while((sarg=(RooAbsArg*)iter->Next())) {
904  // If missing, either import or report error
905  if (!arg(sarg->GetName())) {
906  if (importMissing) {
907  import(*sarg) ;
908  } else {
909  coutE(InputArguments) << "RooWorkspace::defineSet(" << GetName() << ") ERROR set constituent \"" << sarg->GetName()
910  << "\" is not in workspace and importMissing option is disabled" << endl ;
911  return kTRUE ;
912  }
913  }
914  wsargs.add(*arg(sarg->GetName())) ;
915  }
916  delete iter ;
917 
918  // Install named set
919  _namedSets[name].removeAll() ;
920  _namedSets[name].add(wsargs) ;
921 
922  return kFALSE ;
923 }
924 
925 //_____________________________________________________________________________
927 {
928  // Define a named RooArgSet with given constituents. If importMissing is true, any constituents
929  // of aset that are not in the workspace will be imported, otherwise an error is returned
930  // for missing components
931 
932  // Check if set was previously defined, if so print warning
933  map<string, RooArgSet>::iterator i = _namedSets.find(name);
934  if (i != _namedSets.end()) {
935  coutW(InputArguments) << "RooWorkspace::defineSet(" << GetName()
936  << ") WARNING redefining previously defined named set " << name << endl;
937  }
938 
939  // Install named set
940  _namedSets[name].removeAll();
941  _namedSets[name].add(aset);
942 
943  return kFALSE;
944 }
945 
946 ////////////////////////////////////////////////////////////////////////////////
947 /// Define a named set in the work space through a comma separated list of
948 /// names of objects already in the workspace
949 
950 Bool_t RooWorkspace::defineSet(const char* name, const char* contentList)
951 {
952  // Check if set was previously defined, if so print warning
953  map<string,RooArgSet>::iterator i = _namedSets.find(name) ;
954  if (i!=_namedSets.end()) {
955  coutW(InputArguments) << "RooWorkspace::defineSet(" << GetName() << ") WARNING redefining previously defined named set " << name << endl ;
956  }
957 
958  RooArgSet wsargs ;
959 
960  // Check all constituents of provided set
961  char buf[64000];
962  strlcpy(buf, contentList, 64000);
963  char* token = strtok(buf,",") ;
964  while(token) {
965  // If missing, either import or report error
966  if (!arg(token)) {
967  coutE(InputArguments) << "RooWorkspace::defineSet(" << GetName() << ") ERROR proposed set constituent \"" << token
968  << "\" is not in workspace" << endl ;
969  return kTRUE ;
970  }
971  wsargs.add(*arg(token)) ;
972  token = strtok(0,",") ;
973  }
974 
975  // Install named set
976  _namedSets[name].removeAll() ;
977  _namedSets[name].add(wsargs) ;
978 
979  return kFALSE ;
980 }
981 
982 
983 
984 
985 ////////////////////////////////////////////////////////////////////////////////
986 /// Define a named set in the work space through a comma separated list of
987 /// names of objects already in the workspace
988 
989 Bool_t RooWorkspace::extendSet(const char* name, const char* newContents)
990 {
991  RooArgSet wsargs ;
992 
993  // Check all constituents of provided set
994  char buf[64000];
995  strlcpy(buf, newContents, 64000);
996  char* token = strtok(buf,",") ;
997  while(token) {
998  // If missing, either import or report error
999  if (!arg(token)) {
1000  coutE(InputArguments) << "RooWorkspace::defineSet(" << GetName() << ") ERROR proposed set constituent \"" << token
1001  << "\" is not in workspace" << endl ;
1002  return kTRUE ;
1003  }
1004  wsargs.add(*arg(token)) ;
1005  token = strtok(0,",") ;
1006  }
1007 
1008  // Extend named set
1009  _namedSets[name].add(wsargs,kTRUE) ;
1010 
1011  return kFALSE ;
1012 }
1013 
1014 
1015 
1016 ////////////////////////////////////////////////////////////////////////////////
1017 /// Return pointer to previously defined named set with given nmame
1018 /// If no such set is found a null pointer is returned
1019 
1020 const RooArgSet* RooWorkspace::set(const char* name)
1021 {
1022  map<string,RooArgSet>::iterator i = _namedSets.find(name) ;
1023  return (i!=_namedSets.end()) ? &(i->second) : 0 ;
1024 }
1025 
1026 
1027 
1028 
1029 ////////////////////////////////////////////////////////////////////////////////
1030 /// Rename set to a new name
1031 
1032 Bool_t RooWorkspace::renameSet(const char* name, const char* newName)
1033 {
1034  // First check if set exists
1035  if (!set(name)) {
1036  coutE(InputArguments) << "RooWorkspace::renameSet(" << GetName() << ") ERROR a set with name " << name
1037  << " does not exist" << endl ;
1038  return kTRUE ;
1039  }
1040 
1041  // Check if no set exists with new name
1042  if (set(newName)) {
1043  coutE(InputArguments) << "RooWorkspace::renameSet(" << GetName() << ") ERROR a set with name " << newName
1044  << " already exists" << endl ;
1045  return kTRUE ;
1046  }
1047 
1048  // Copy entry under 'name' to 'newName'
1049  _namedSets[newName].add(_namedSets[name]) ;
1050 
1051  // Remove entry under old name
1052  _namedSets.erase(name) ;
1053 
1054  return kFALSE ;
1055 }
1056 
1057 
1058 
1059 
1060 ////////////////////////////////////////////////////////////////////////////////
1061 /// Remove a named set from the workspace
1062 
1064 {
1065  // First check if set exists
1066  if (!set(name)) {
1067  coutE(InputArguments) << "RooWorkspace::removeSet(" << GetName() << ") ERROR a set with name " << name
1068  << " does not exist" << endl ;
1069  return kTRUE ;
1070  }
1071 
1072  // Remove set with given name
1073  _namedSets.erase(name) ;
1074 
1075  return kFALSE ;
1076 }
1077 
1078 
1079 
1080 
1081 ////////////////////////////////////////////////////////////////////////////////
1082 /// Open an import transaction operations. Returns kTRUE if successful, kFALSE
1083 /// if there is already an ongoing transaction
1084 
1086 {
1087  // Check that there was no ongoing transaction
1088  if (_openTrans) {
1089  return kFALSE ;
1090  }
1091 
1092  // Open transaction
1093  _openTrans = kTRUE ;
1094  return kTRUE ;
1095 }
1096 
1097 
1098 
1099 
1100 ////////////////////////////////////////////////////////////////////////////////
1101 /// Cancel an ongoing import transaction. All objects imported since startTransaction()
1102 /// will be removed and the transaction will be terminated. Return kTRUE if cancel operation
1103 /// succeeds, return kFALSE if there was no open transaction
1104 
1106 {
1107  // Check that there is an ongoing transaction
1108  if (!_openTrans) {
1109  return kFALSE ;
1110  }
1111 
1112  // Delete all objects in the sandbox
1114  RooAbsArg* tmpArg ;
1115  while((tmpArg=(RooAbsArg*)iter->Next())) {
1116  _allOwnedNodes.remove(*tmpArg) ;
1117  }
1118  delete iter ;
1120 
1121  // Mark transaction as finished
1122  _openTrans = kFALSE ;
1123 
1124  return kTRUE ;
1125 }
1126 
1128 {
1129  // Commit an ongoing import transaction. Returns kTRUE if commit succeeded,
1130  // return kFALSE if there was no ongoing transaction
1131 
1132  // Check that there is an ongoing transaction
1133  if (!_openTrans) {
1134  return kFALSE ;
1135  }
1136 
1137  // Publish sandbox nodes in directory and/or CINT if requested
1139  RooAbsArg* sarg ;
1140  while((sarg=(RooAbsArg*)iter->Next())) {
1141  if (_dir && sarg->IsA() != RooConstVar::Class()) {
1142  _dir->InternalAppend(sarg) ;
1143  }
1144  if (_doExport && sarg->IsA() != RooConstVar::Class()) {
1145  exportObj(sarg) ;
1146  }
1147  }
1148  delete iter ;
1149 
1150  // Remove all committed objects from the sandbox
1152 
1153  // Mark transaction as finished
1154  _openTrans = kFALSE ;
1155 
1156  return kTRUE ;
1157 }
1158 
1159 
1160 
1161 
1162 ////////////////////////////////////////////////////////////////////////////////
1163 
1165 {
1166  return _classes.autoImportClass(theClass,doReplace) ;
1167 }
1168 
1169 
1170 
1171 ////////////////////////////////////////////////////////////////////////////////
1172 /// Inport code of all classes in the workspace that have a class name
1173 /// that matches pattern 'pat' and which are not found to be part of
1174 /// the standard ROOT distribution. If doReplace is true any existing
1175 /// class code saved in the workspace is replaced
1176 
1177 Bool_t RooWorkspace::importClassCode(const char* pat, Bool_t doReplace)
1178 {
1179  Bool_t ret(kTRUE) ;
1180 
1181  TRegexp re(pat,kTRUE) ;
1182  TIterator* iter = componentIterator() ;
1183  RooAbsArg* carg ;
1184  while((carg=(RooAbsArg*)iter->Next())) {
1185  TString className = carg->IsA()->GetName() ;
1186  if (className.Index(re)>=0 && !_classes.autoImportClass(carg->IsA(),doReplace)) {
1187  coutW(ObjectHandling) << "RooWorkspace::import(" << GetName() << ") WARNING: problems import class code of object "
1188  << carg->IsA()->GetName() << "::" << carg->GetName() << ", reading of workspace will require external definition of class" << endl ;
1189  ret = kFALSE ;
1190  }
1191  }
1192  delete iter ;
1193 
1194  return ret ;
1195 }
1196 
1197 
1198 
1199 
1200 
1201 ////////////////////////////////////////////////////////////////////////////////
1202 /// Save snapshot of values and attributes (including "Constant") of parameters 'params'
1203 /// If importValues is FALSE, the present values from the object in the workspace are
1204 /// saved. If importValues is TRUE, the values of the objects passed in the 'params'
1205 /// argument are saved
1206 
1207 Bool_t RooWorkspace::saveSnapshot(const char* name, const char* paramNames)
1208 {
1209  return saveSnapshot(name,argSet(paramNames),kFALSE) ;
1210 }
1211 
1212 
1213 
1214 
1215 
1216 ////////////////////////////////////////////////////////////////////////////////
1217 /// Save snapshot of values and attributes (including "Constant") of parameters 'params'
1218 /// If importValues is FALSE, the present values from the object in the workspace are
1219 /// saved. If importValues is TRUE, the values of the objects passed in the 'params'
1220 /// argument are saved
1221 
1222 Bool_t RooWorkspace::saveSnapshot(const char* name, const RooArgSet& params, Bool_t importValues)
1223 {
1224  RooArgSet* actualParams = (RooArgSet*) _allOwnedNodes.selectCommon(params) ;
1225  RooArgSet* snapshot = (RooArgSet*) actualParams->snapshot() ;
1226  delete actualParams ;
1227 
1228  snapshot->setName(name) ;
1229 
1230  if (importValues) {
1231  *snapshot = params ;
1232  }
1233 
1234  RooArgSet* oldSnap = (RooArgSet*) _snapshots.FindObject(name) ;
1235  if (oldSnap) {
1236  coutI(ObjectHandling) << "RooWorkspace::saveSnaphot(" << GetName() << ") replacing previous snapshot with name " << name << endl ;
1237  _snapshots.Remove(oldSnap) ;
1238  delete oldSnap ;
1239  }
1240 
1241  _snapshots.Add(snapshot) ;
1242 
1243  return kTRUE ;
1244 }
1245 
1246 
1247 
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 /// Load the values and attributes of the parameters in the snapshot saved with
1251 /// the given name
1252 
1254 {
1255  RooArgSet* snap = (RooArgSet*) _snapshots.find(name) ;
1256  if (!snap) {
1257  coutE(ObjectHandling) << "RooWorkspace::loadSnapshot(" << GetName() << ") no snapshot with name " << name << " is available" << endl ;
1258  return kFALSE ;
1259  }
1260 
1261  RooArgSet* actualParams = (RooArgSet*) _allOwnedNodes.selectCommon(*snap) ;
1262  *actualParams = *snap ;
1263  delete actualParams ;
1264 
1265  return kTRUE ;
1266 }
1267 
1268 
1269 ////////////////////////////////////////////////////////////////////////////////
1270 /// Return the RooArgSet containgin a snapshot of variables contained in the workspace
1271 ///
1272 /// Note that the variables of the objects in the snapshots are _copies_ of the
1273 /// variables in the workspace. To load the values of a snapshot in the workspace
1274 /// variables use loadSnapshot() instead
1275 
1276 const RooArgSet* RooWorkspace::getSnapshot(const char* name) const
1277 {
1278  RooArgSet* snap = (RooArgSet*) _snapshots.find(name) ;
1279  if (!snap) {
1280  coutE(ObjectHandling) << "RooWorkspace::loadSnapshot(" << GetName() << ") no snapshot with name " << name << " is available" << endl ;
1281  return 0 ;
1282  }
1283 
1284  return snap ;
1285 }
1286 
1287 
1288 
1289 // //_____________________________________________________________________________
1290 // RooAbsPdf* RooWorkspace::joinPdf(const char* jointPdfName, const char* indexName, const char* inputMapping)
1291 // {
1292 // // Join given list of p.d.f.s into a simultaneous p.d.f with given name. If the named index category
1293 // // does not exist, it is created.
1294 // //
1295 // // Example : joinPdf("simPdf","expIndex","A=pdfA,B=pdfB") ;
1296 // //
1297 // // will return a RooSimultaneous named 'simPdf' with index category 'expIndex' with
1298 // // state names A and B. Pdf 'pdfA' will be associated with state A and pdf 'pdfB'
1299 // // will be associated with state B
1300 // //
1301 // return 0 ;
1302 // }
1303 
1304 // //_____________________________________________________________________________
1305 // RooAbsData* RooWorkspace::joinData(const char* jointDataName, const char* indexName, const char* inputMapping)
1306 // {
1307 // // Join given list of dataset into a joint dataset for use with a simultaneous pdf
1308 // // (as e.g. created by joingPdf"
1309 // //
1310 // // Example : joinData("simData","expIndex","A=dataA,B=dataB") ;
1311 // //
1312 // // will return a RooDataSet named 'simData' that consist of the entries of both
1313 // // dataA and dataB. An extra category column 'expIndex' is added that labels
1314 // // each entry with state 'A' and 'B' to indicate the originating dataset
1315 // return 0 ;
1316 // }
1317 
1318 
1319 ////////////////////////////////////////////////////////////////////////////////
1320 /// Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found
1321 
1322 RooAbsPdf* RooWorkspace::pdf(const char* name) const
1323 {
1324  return dynamic_cast<RooAbsPdf*>(_allOwnedNodes.find(name)) ;
1325 }
1326 
1327 
1328 ////////////////////////////////////////////////////////////////////////////////
1329 /// Retrieve function (RooAbsReal) with given name. Note that all RooAbsPdfs are also RooAbsReals. A null pointer is returned if not found.
1330 
1332 {
1333  return dynamic_cast<RooAbsReal*>(_allOwnedNodes.find(name)) ;
1334 }
1335 
1336 
1337 ////////////////////////////////////////////////////////////////////////////////
1338 /// Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found
1339 
1340 RooRealVar* RooWorkspace::var(const char* name) const
1341 {
1342  return dynamic_cast<RooRealVar*>(_allOwnedNodes.find(name)) ;
1343 }
1344 
1345 
1346 ////////////////////////////////////////////////////////////////////////////////
1347 /// Retrieve discrete variable (RooCategory) with given name. A null pointer is returned if not found
1348 
1350 {
1351  return dynamic_cast<RooCategory*>(_allOwnedNodes.find(name)) ;
1352 }
1353 
1354 
1355 ////////////////////////////////////////////////////////////////////////////////
1356 /// Retrieve discrete function (RooAbsCategory) with given name. A null pointer is returned if not found
1357 
1359 {
1360  return dynamic_cast<RooAbsCategory*>(_allOwnedNodes.find(name)) ;
1361 }
1362 
1363 
1364 
1365 ////////////////////////////////////////////////////////////////////////////////
1366 /// Return RooAbsArg with given name. A null pointer is returned if none is found.
1367 
1368 RooAbsArg* RooWorkspace::arg(const char* name) const
1369 {
1370  return _allOwnedNodes.find(name) ;
1371 }
1372 
1373 
1374 
1375 ////////////////////////////////////////////////////////////////////////////////
1376 /// Return set of RooAbsArgs matching to given list of names
1377 
1378 RooArgSet RooWorkspace::argSet(const char* nameList) const
1379 {
1380  RooArgSet ret ;
1381 
1382  char tmp[64000];
1383  strlcpy(tmp, nameList, 64000);
1384  char* token = strtok(tmp,",") ;
1385  while(token) {
1386  RooAbsArg* oneArg = arg(token) ;
1387  if (oneArg) {
1388  ret.add(*oneArg) ;
1389  } else {
1390  coutE(InputArguments) << " RooWorkspace::argSet(" << GetName() << ") no RooAbsArg named \"" << token << "\" in workspace" << endl ;
1391  }
1392  token = strtok(0,",") ;
1393  }
1394  return ret ;
1395 }
1396 
1397 
1398 
1399 ////////////////////////////////////////////////////////////////////////////////
1400 /// Return fundamental (i.e. non-derived) RooAbsArg with given name. Fundamental types
1401 /// are e.g. RooRealVar, RooCategory. A null pointer is returned if none is found.
1402 
1404 {
1405  RooAbsArg* tmp = arg(name) ;
1406  if (!tmp) {
1407  return 0 ;
1408  }
1409  return tmp->isFundamental() ? tmp : 0 ;
1410 }
1411 
1412 
1413 
1414 ////////////////////////////////////////////////////////////////////////////////
1415 /// Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found
1416 
1418 {
1419  return (RooAbsData*)_dataList.FindObject(name) ;
1420 }
1421 
1422 
1423 ////////////////////////////////////////////////////////////////////////////////
1424 /// Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found
1425 
1427 {
1428  return (RooAbsData*)_embeddedDataList.FindObject(name) ;
1429 }
1430 
1431 
1432 
1433 
1434 ////////////////////////////////////////////////////////////////////////////////
1435 /// Return set with all variable objects
1436 
1438 {
1439  RooArgSet ret ;
1440 
1441  // Split list of components in pdfs, functions and variables
1443  RooAbsArg* parg ;
1444  while((parg=(RooAbsArg*)iter->Next())) {
1445  if (parg->IsA()->InheritsFrom(RooRealVar::Class())) {
1446  ret.add(*parg) ;
1447  }
1448  }
1449  delete iter ;
1450 
1451  return ret ;
1452 }
1453 
1454 
1455 ////////////////////////////////////////////////////////////////////////////////
1456 /// Return set with all category objects
1457 
1459 {
1460  RooArgSet ret ;
1461 
1462  // Split list of components in pdfs, functions and variables
1464  RooAbsArg* parg ;
1465  while((parg=(RooAbsArg*)iter->Next())) {
1466  if (parg->IsA()->InheritsFrom(RooCategory::Class())) {
1467  ret.add(*parg) ;
1468  }
1469  }
1470  delete iter ;
1471 
1472  return ret ;
1473 }
1474 
1475 
1476 
1477 ////////////////////////////////////////////////////////////////////////////////
1478 /// Return set with all function objects
1479 
1481 {
1482  RooArgSet ret ;
1483 
1484  // Split list of components in pdfs, functions and variables
1486  RooAbsArg* parg ;
1487  while((parg=(RooAbsArg*)iter->Next())) {
1488  if (parg->IsA()->InheritsFrom(RooAbsReal::Class()) &&
1489  !parg->IsA()->InheritsFrom(RooAbsPdf::Class()) &&
1490  !parg->IsA()->InheritsFrom(RooConstVar::Class()) &&
1491  !parg->IsA()->InheritsFrom(RooRealVar::Class())) {
1492  ret.add(*parg) ;
1493  }
1494  }
1495 
1496  return ret ;
1497 }
1498 
1499 
1500 ////////////////////////////////////////////////////////////////////////////////
1501 /// Return set with all category function objects
1502 
1504 {
1505  RooArgSet ret ;
1506 
1507  // Split list of components in pdfs, functions and variables
1509  RooAbsArg* parg ;
1510  while((parg=(RooAbsArg*)iter->Next())) {
1511  if (parg->IsA()->InheritsFrom(RooAbsCategory::Class()) &&
1512  !parg->IsA()->InheritsFrom(RooCategory::Class())) {
1513  ret.add(*parg) ;
1514  }
1515  }
1516  return ret ;
1517 }
1518 
1519 
1520 
1521 ////////////////////////////////////////////////////////////////////////////////
1522 /// Return set with all resolution model objects
1523 
1525 {
1526  RooArgSet ret ;
1527 
1528  // Split list of components in pdfs, functions and variables
1530  RooAbsArg* parg ;
1531  while((parg=(RooAbsArg*)iter->Next())) {
1532  if (parg->IsA()->InheritsFrom(RooResolutionModel::Class())) {
1533  if (!((RooResolutionModel*)parg)->isConvolved()) {
1534  ret.add(*parg) ;
1535  }
1536  }
1537  }
1538  return ret ;
1539 }
1540 
1541 
1542 ////////////////////////////////////////////////////////////////////////////////
1543 /// Return set with all probability density function objects
1544 
1546 {
1547  RooArgSet ret ;
1548 
1549  // Split list of components in pdfs, functions and variables
1551  RooAbsArg* parg ;
1552  while((parg=(RooAbsArg*)iter->Next())) {
1553  if (parg->IsA()->InheritsFrom(RooAbsPdf::Class()) &&
1554  !parg->IsA()->InheritsFrom(RooResolutionModel::Class())) {
1555  ret.add(*parg) ;
1556  }
1557  }
1558  return ret ;
1559 }
1560 
1561 
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// Return list of all dataset in the workspace
1565 
1566 list<RooAbsData*> RooWorkspace::allData() const
1567 {
1568  list<RooAbsData*> ret ;
1569  TIterator* iter = _dataList.MakeIterator() ;
1570  RooAbsData* dat ;
1571  while((dat=(RooAbsData*)iter->Next())) {
1572  ret.push_back(dat) ;
1573  }
1574  delete iter ;
1575  return ret ;
1576 }
1577 
1578 
1579 ////////////////////////////////////////////////////////////////////////////////
1580 /// Return list of all dataset in the workspace
1581 
1582 list<RooAbsData*> RooWorkspace::allEmbeddedData() const
1583 {
1584  list<RooAbsData*> ret ;
1586  RooAbsData* dat ;
1587  while((dat=(RooAbsData*)iter->Next())) {
1588  ret.push_back(dat) ;
1589  }
1590  delete iter ;
1591  return ret ;
1592 }
1593 
1594 
1595 
1596 ////////////////////////////////////////////////////////////////////////////////
1597 /// Return list of all generic objects in the workspace
1598 
1599 list<TObject*> RooWorkspace::allGenericObjects() const
1600 {
1601  list<TObject*> ret ;
1602  TIterator* iter = _genObjects.MakeIterator() ;
1603  TObject* gobj ;
1604  while((gobj=(RooAbsData*)iter->Next())) {
1605 
1606  // If found object is wrapper, return payload
1607  if (gobj->IsA()==RooTObjWrap::Class()) {
1608  ret.push_back(((RooTObjWrap*)gobj)->obj()) ;
1609  } else {
1610  ret.push_back(gobj) ;
1611  }
1612  }
1613  delete iter ;
1614  return ret ;
1615 }
1616 
1617 
1618 
1619 
1620 ////////////////////////////////////////////////////////////////////////////////
1621 /// Import code of class 'tc' into the repository. If code is already in repository it is only imported
1622 /// again if doReplace is false. The names and location of the source files is determined from the information
1623 /// in TClass. If no location is found in the TClass information, the files are searched in the workspace
1624 /// search path, defined by addClassDeclImportDir() and addClassImplImportDir() for declaration and implementation
1625 /// files respectively. If files cannot be found, abort with error status, otherwise update the internal
1626 /// class-to-file map and import the contents of the files, if they are not imported yet.
1627 
1629 {
1630 
1631  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo(" << _wspace->GetName() << ") request to import code of class " << tc->GetName() << endl ;
1632 
1633  // *** PHASE 1 *** Check if file needs to be imported, or is in ROOT distribution, and check if it can be persisted
1634 
1635  // Check if we already have the class (i.e. it is in the classToFile map)
1636  if (!doReplace && _c2fmap.find(tc->GetName())!=_c2fmap.end()) {
1637  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo(" << _wspace->GetName() << ") code of class " << tc->GetName() << " already imported, skipping" << endl ;
1638  return kTRUE ;
1639  }
1640 
1641  // Check if class is listed in a ROOTMAP file - if so we can skip it because it is in the root distribtion
1642  const char* mapEntry = gInterpreter->GetClassSharedLibs(tc->GetName()) ;
1643  if (mapEntry && strlen(mapEntry)>0) {
1644  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo(" << _wspace->GetName() << ") code of class " << tc->GetName() << " is in ROOT distribution, skipping " << endl ;
1645  return kTRUE ;
1646  }
1647 
1648  // Retrieve file names through ROOT TClass interface
1649  string implfile = tc->GetImplFileName() ;
1650  string declfile = tc->GetDeclFileName() ;
1651 
1652  // Check that file names are not empty
1653  if (implfile.empty() || declfile.empty()) {
1654  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo(" << _wspace->GetName() << ") ERROR: cannot retrieve code file names for class "
1655  << tc->GetName() << " through ROOT TClass interface, unable to import code" << endl ;
1656  return kFALSE ;
1657  }
1658 
1659  // Check if header filename is found in ROOT distribution, if so, do not import class
1660  TString rootsys = gSystem->Getenv("ROOTSYS") ;
1661  if (TString(implfile.c_str()).Index(rootsys)>=0) {
1662  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo(" << _wspace->GetName() << ") code of class " << tc->GetName() << " is in ROOT distribution, skipping " << endl ;
1663  return kTRUE ;
1664  }
1665  const char* implpath=0 ;
1666 
1667  // Require that class meets technical criteria to be persistable (i.e it has a default ctor)
1668  // (We also need a default ctor of abstract classes, but cannot check that through is interface
1669  // as TClass::HasDefaultCtor only returns true for callable default ctors)
1670  if (!(tc->Property() & kIsAbstract) && !tc->HasDefaultConstructor()) {
1671  oocoutW(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName() << ") WARNING cannot import class "
1672  << tc->GetName() << " : it cannot be persisted because it doesn't have a default constructor. Please fix " << endl ;
1673  return kFALSE ;
1674  }
1675 
1676 
1677  // *** PHASE 2 *** Check if declaration and implementation files can be located
1678 
1679  char* declpath = 0 ;
1680 
1681  // Check if header file can be found in specified location
1682  // If not, scan through list of 'class declaration' paths in RooWorkspace
1683  if (gSystem->AccessPathName(declfile.c_str())) {
1684 
1685  // Check list of additional declaration paths
1686  list<string>::iterator diter = RooWorkspace::_classDeclDirList.begin() ;
1687 
1688  while(diter!= RooWorkspace::_classDeclDirList.end()) {
1689 
1690  declpath = gSystem->ConcatFileName(diter->c_str(),declfile.c_str()) ;
1691  if (!gSystem->AccessPathName(declpath)) {
1692  // found declaration file
1693  break ;
1694  }
1695  // cleanup and continue ;
1696  delete[] declpath ;
1697  declpath=0 ;
1698 
1699  ++diter ;
1700  }
1701 
1702  // Header file cannot be found anywhere, warn user and abort operation
1703  if (!declpath) {
1704  oocoutW(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName() << ") WARNING Cannot access code of class "
1705  << tc->GetName() << " because header file " << declfile << " is not found in current directory nor in $ROOTSYS" ;
1706  if (_classDeclDirList.size()>0) {
1707  ooccoutW(_wspace,ObjectHandling) << ", nor in the search path " ;
1708  diter = RooWorkspace::_classDeclDirList.begin() ;
1709 
1710  while(diter!= RooWorkspace::_classDeclDirList.end()) {
1711 
1712  if (diter!=RooWorkspace::_classDeclDirList.begin()) {
1713  ooccoutW(_wspace,ObjectHandling) << "," ;
1714  }
1715  ooccoutW(_wspace,ObjectHandling) << diter->c_str() ;
1716  ++diter ;
1717  }
1718  }
1719  ooccoutW(_wspace,ObjectHandling) << ". To fix this problem add the required directory to the search "
1720  << "path using RooWorkspace::addClassDeclDir(const char* dir)" << endl ;
1721 
1722  return kFALSE ;
1723  }
1724  }
1725 
1726 
1727  // Check if implementation file can be found in specified location
1728  // If not, scan through list of 'class implementation' paths in RooWorkspace
1729  if (gSystem->AccessPathName(implfile.c_str())) {
1730 
1731  // Check list of additional declaration paths
1732  list<string>::iterator iiter = RooWorkspace::_classImplDirList.begin() ;
1733 
1734  while(iiter!= RooWorkspace::_classImplDirList.end()) {
1735 
1736  implpath = gSystem->ConcatFileName(iiter->c_str(),implfile.c_str()) ;
1737  if (!gSystem->AccessPathName(implpath)) {
1738  // found implementation file
1739  break ;
1740  }
1741  // cleanup and continue ;
1742  delete[] implpath ;
1743  implpath=0 ;
1744 
1745  ++iiter ;
1746  }
1747 
1748  // Implementation file cannot be found anywhere, warn user and abort operation
1749  if (!implpath) {
1750  oocoutW(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName() << ") WARNING Cannot access code of class "
1751  << tc->GetName() << " because implementation file " << implfile << " is not found in current directory nor in $ROOTSYS" ;
1752  if (_classDeclDirList.size()>0) {
1753  ooccoutW(_wspace,ObjectHandling) << ", nor in the search path " ;
1754  iiter = RooWorkspace::_classImplDirList.begin() ;
1755 
1756  while(iiter!= RooWorkspace::_classImplDirList.end()) {
1757 
1758  if (iiter!=RooWorkspace::_classImplDirList.begin()) {
1759  ooccoutW(_wspace,ObjectHandling) << "," ;
1760  }
1761  ooccoutW(_wspace,ObjectHandling) << iiter->c_str() ;
1762  ++iiter ;
1763  }
1764  }
1765  ooccoutW(_wspace,ObjectHandling) << ". To fix this problem add the required directory to the search "
1766  << "path using RooWorkspace::addClassImplDir(const char* dir)" << endl ;
1767  return kFALSE ;
1768  }
1769  }
1770 
1771  char buf[64000];
1772 
1773  // *** Phase 3 *** Prepare to import code from files into STL string buffer
1774  //
1775  // Code storage is organized in two linked maps
1776  //
1777  // _fmap contains stl strings with code, indexed on declaration file name
1778  //
1779  // _c2fmap contains list of declaration file names and list of base classes
1780  // and is indexed on class name
1781  //
1782  // Phase 3 is skipped if fmap already contains an entry with given filebasename
1783 
1784  string declfilename = declpath?gSystem->BaseName(declpath):gSystem->BaseName(declfile.c_str()) ;
1785 
1786  // Split in base and extension
1787  int dotpos2 = strrchr(declfilename.c_str(),'.') - declfilename.c_str() ;
1788  string declfilebase = declfilename.substr(0,dotpos2) ;
1789  string declfileext = declfilename.substr(dotpos2+1) ;
1790 
1791  list<string> extraHeaders ;
1792 
1793  // If file has not beed stored yet, enter stl strings with implementation and declaration in file map
1794  if (_fmap.find(declfilebase) == _fmap.end()) {
1795 
1796  // Open declaration file
1797  fstream fdecl(declpath?declpath:declfile.c_str()) ;
1798 
1799  // Abort import if declaration file cannot be opened
1800  if (!fdecl) {
1801  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1802  << ") ERROR opening declaration file " << declfile << endl ;
1803  return kFALSE ;
1804  }
1805 
1806  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1807  << ") importing code of class " << tc->GetName()
1808  << " from " << (implpath?implpath:implfile.c_str())
1809  << " and " << (declpath?declpath:declfile.c_str()) << endl ;
1810 
1811 
1812  // Read entire file into an stl string
1813  string decl ;
1814  while(fdecl.getline(buf,1023)) {
1815 
1816  // Look for include state of self
1817  Bool_t processedInclude = kFALSE ;
1818  char* extincfile = 0 ;
1819 
1820  // Look for include of declaration file corresponding to this implementation file
1821  if (strstr(buf,"#include")) {
1822  // Process #include statements here
1823  char tmp[64000];
1824  strlcpy(tmp, buf, 64000);
1825  Bool_t stdinclude = strchr(buf, '<');
1826  strtok(tmp, " <\"");
1827  char *incfile = strtok(0, " <>\"");
1828 
1829  if (!stdinclude) {
1830  // check if it lives in $ROOTSYS/include
1831  TString hpath = gSystem->Getenv("ROOTSYS");
1832  hpath += "/include/";
1833  hpath += incfile;
1834  if (gSystem->AccessPathName(hpath.Data())) {
1835  oocoutI(_wspace, ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1836  << ") scheduling include file " << incfile << " for import" << endl;
1837  extraHeaders.push_back(incfile);
1838  extincfile = incfile;
1839  processedInclude = kTRUE;
1840  }
1841  }
1842  }
1843 
1844  if (processedInclude) {
1845  decl += "// external include file below retrieved from workspace code storage\n" ;
1846  decl += Form("#include \"%s\"\n",extincfile) ;
1847  } else {
1848  decl += buf ;
1849  decl += '\n' ;
1850  }
1851  }
1852 
1853  // Open implementation file
1854  fstream fimpl(implpath?implpath:implfile.c_str()) ;
1855 
1856  // Abort import if implementation file cannot be opened
1857  if (!fimpl) {
1858  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1859  << ") ERROR opening implementation file " << implfile << endl ;
1860  return kFALSE ;
1861  }
1862 
1863 
1864  // Import entire implentation file into stl string
1865  string impl ;
1866  while(fimpl.getline(buf,1023)) {
1867  // Process #include statements here
1868 
1869  // Look for include state of self
1870  Bool_t foundSelfInclude=kFALSE ;
1871  Bool_t processedInclude = kFALSE ;
1872  char* extincfile = 0 ;
1873 
1874  // Look for include of declaration file corresponding to this implementation file
1875  if (strstr(buf,"#include")) {
1876  // Process #include statements here
1877  char tmp[64000];
1878  strlcpy(tmp, buf, 64000);
1879  Bool_t stdinclude = strchr(buf, '<');
1880  strtok(tmp, " <\"");
1881  char *incfile = strtok(0, " <>\"");
1882 
1883  if (strstr(incfile, declfilename.c_str())) {
1884  foundSelfInclude = kTRUE;
1885  }
1886 
1887  if (!stdinclude && !foundSelfInclude) {
1888  // check if it lives in $ROOTSYS/include
1889  TString hpath = gSystem->Getenv("ROOTSYS");
1890  hpath += "/include/";
1891  hpath += incfile;
1892 
1893  if (gSystem->AccessPathName(hpath.Data())) {
1894  oocoutI(_wspace, ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1895  << ") scheduling include file " << incfile << " for import" << endl;
1896  extraHeaders.push_back(incfile);
1897  extincfile = incfile;
1898  processedInclude = kTRUE;
1899  }
1900  }
1901  }
1902 
1903  // Explicitly rewrite include of own declaration file to string
1904  // any directory prefixes, copy all other lines verbatim in stl string
1905  if (foundSelfInclude) {
1906  // If include of self is found, substitute original include
1907  // which may have directory structure with a plain include
1908  impl += "// class declaration include file below retrieved from workspace code storage\n" ;
1909  impl += Form("#include \"%s.%s\"\n",declfilebase.c_str(),declfileext.c_str()) ;
1910  } else if (processedInclude) {
1911  impl += "// external include file below retrieved from workspace code storage\n" ;
1912  impl += Form("#include \"%s\"\n",extincfile) ;
1913  } else {
1914  impl += buf ;
1915  impl += '\n' ;
1916  }
1917  }
1918 
1919  // Create entry in file map
1920  _fmap[declfilebase]._hfile = decl ;
1921  _fmap[declfilebase]._cxxfile = impl ;
1922  _fmap[declfilebase]._hext = declfileext ;
1923 
1924  // Process extra includes now
1925  for (list<string>::iterator ehiter = extraHeaders.begin() ; ehiter != extraHeaders.end() ; ++ehiter ) {
1926  if (_ehmap.find(*ehiter) == _ehmap.end()) {
1927 
1928  ExtraHeader eh ;
1929  eh._hname = ehiter->c_str() ;
1930  fstream fehdr(ehiter->c_str()) ;
1931  string ehimpl ;
1932  char buf2[1024] ;
1933  while(fehdr.getline(buf2,1023)) {
1934 
1935  // Look for include of declaration file corresponding to this implementation file
1936  if (strstr(buf2,"#include")) {
1937  // Process #include statements here
1938  char tmp[64000];
1939  strlcpy(tmp, buf2, 64000);
1940  Bool_t stdinclude = strchr(buf, '<');
1941  strtok(tmp, " <\"");
1942  char *incfile = strtok(0, " <>\"");
1943 
1944  if (!stdinclude) {
1945  // check if it lives in $ROOTSYS/include
1946  TString hpath = gSystem->Getenv("ROOTSYS");
1947  hpath += "/include/";
1948  hpath += incfile;
1949  if (gSystem->AccessPathName(hpath.Data())) {
1950  oocoutI(_wspace, ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1951  << ") scheduling recursive include file " << incfile << " for import"
1952  << endl;
1953  extraHeaders.push_back(incfile);
1954  }
1955  }
1956  }
1957 
1958  ehimpl += buf2;
1959  ehimpl += '\n';
1960  }
1961  eh._hfile = ehimpl.c_str();
1962 
1963  _ehmap[ehiter->c_str()] = eh;
1964  }
1965  }
1966 
1967  } else {
1968 
1969  // Inform that existing file entry is being recycled because it already contained class code
1970  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::autoImportClass(" << _wspace->GetName()
1971  << ") code of class " << tc->GetName()
1972  << " was already imported from " << (implpath?implpath:implfile.c_str())
1973  << " and " << (declpath?declpath:declfile.c_str()) << endl ;
1974 
1975  }
1976 
1977 
1978  // *** PHASE 4 *** Import stl strings with code into workspace
1979  //
1980  // If multiple classes are declared in a single code unit, there will be
1981  // multiple _c2fmap entries all pointing to the same _fmap entry.
1982 
1983  // Make list of all immediate base classes of this class
1984  TString baseNameList ;
1985  TList* bl = tc->GetListOfBases() ;
1986  TIterator* iter = bl->MakeIterator() ;
1987  TBaseClass* base ;
1988  list<TClass*> bases ;
1989  while((base=(TBaseClass*)iter->Next())) {
1990  if (baseNameList.Length()>0) {
1991  baseNameList += "," ;
1992  }
1993  baseNameList += base->GetClassPointer()->GetName() ;
1994  bases.push_back(base->GetClassPointer()) ;
1995  }
1996 
1997  // Map class name to above _fmap entries, along with list of base classes
1998  // in _c2fmap
1999  _c2fmap[tc->GetName()]._baseName = baseNameList ;
2000  _c2fmap[tc->GetName()]._fileBase = declfilebase ;
2001 
2002  // Recursive store all base classes.
2003  list<TClass*>::iterator biter = bases.begin() ;
2004  while(biter!=bases.end()) {
2005  autoImportClass(*biter,doReplace) ;
2006  ++biter ;
2007  }
2008 
2009  // Cleanup
2010  if (implpath) {
2011  delete[] implpath ;
2012  }
2013  if (declpath) {
2014  delete[] declpath ;
2015  }
2016 
2017 
2018  return kTRUE ;
2019 }
2020 
2021 
2022 ////////////////////////////////////////////////////////////////////////////////
2023 /// Create transient TDirectory representation of this workspace. This directory
2024 /// will appear as a subdirectory of the directory that contains the workspace
2025 /// and will have the name of the workspace suffixed with "Dir". The TDirectory
2026 /// interface is read-only. Any attempt to insert objects into the workspace
2027 /// directory representation will result in an error message. Note that some
2028 /// ROOT object like TH1 automatically insert themselves into the current directory
2029 /// when constructed. This will give error messages when done in a workspace
2030 /// directory.
2031 
2033 {
2034  if (_dir) return kTRUE ;
2035 
2036  TString title= Form("TDirectory representation of RooWorkspace %s",GetName()) ;
2037  _dir = new WSDir(GetName(),title.Data(),this) ;
2038 
2039  TIterator* iter = componentIterator() ;
2040  RooAbsArg* darg ;
2041  while((darg=(RooAbsArg*)iter->Next())) {
2042  if (darg->IsA() != RooConstVar::Class()) {
2043  _dir->InternalAppend(darg) ;
2044  }
2045  }
2046 
2047  return kTRUE ;
2048 }
2049 
2050 
2051 
2052 ////////////////////////////////////////////////////////////////////////////////
2053 /// Import a clone of a generic TObject into workspace generic object container. Imported
2054 /// object can be retrieved by name through the obj() method. The object is cloned upon
2055 /// importation and the input argument does not need to live beyond the import call
2056 ///
2057 /// Returns kTRUE if an error has occurred.
2058 
2059 Bool_t RooWorkspace::import(TObject& object, Bool_t replaceExisting)
2060 {
2061  // First check if object with given name already exists
2062  TObject* oldObj = _genObjects.FindObject(object.GetName()) ;
2063  if (oldObj && !replaceExisting) {
2064  coutE(InputArguments) << "RooWorkspace::import(" << GetName() << ") generic object with name "
2065  << object.GetName() << " is already in workspace and replaceExisting flag is set to false" << endl ;
2066  return kTRUE ;
2067  }
2068 
2069  // Grab the current state of the directory Auto-Add
2070  ROOT::DirAutoAdd_t func = object.IsA()->GetDirectoryAutoAdd();
2071  object.IsA()->SetDirectoryAutoAdd(0);
2073 
2074  if (oldObj) {
2075  _genObjects.Replace(oldObj,object.Clone()) ;
2076  delete oldObj ;
2077  } else {
2078  _genObjects.Add(object.Clone()) ;
2079  }
2080 
2081  // Reset the state of the directory Auto-Add
2082  object.IsA()->SetDirectoryAutoAdd(func);
2084 
2085  return kFALSE ;
2086 }
2087 
2088 
2089 
2090 
2091 ////////////////////////////////////////////////////////////////////////////////
2092 /// Import a clone of a generic TObject into workspace generic object container.
2093 /// The imported object will be stored under the given alias name rather than its
2094 /// own name. Imported object can be retrieved its alias name through the obj() method.
2095 /// The object is cloned upon importation and the input argument does not need to live beyond the import call
2096 /// This method is mostly useful for importing objects that do not have a settable name such as TMatrix
2097 ///
2098 /// Returns kTRUE if an error has occurred.
2099 
2100 Bool_t RooWorkspace::import(TObject& object, const char* aliasName, Bool_t replaceExisting)
2101 {
2102  // First check if object with given name already exists
2103  TObject* oldObj = _genObjects.FindObject(object.GetName()) ;
2104  if (oldObj && !replaceExisting) {
2105  coutE(InputArguments) << "RooWorkspace::import(" << GetName() << ") generic object with name "
2106  << object.GetName() << " is already in workspace and replaceExisting flag is set to false" << endl ;
2107  return kTRUE ;
2108  }
2109 
2111  RooTObjWrap* wrapper = new RooTObjWrap(object.Clone()) ;
2113  wrapper->setOwning(kTRUE) ;
2114  wrapper->SetName(aliasName) ;
2115  wrapper->SetTitle(aliasName) ;
2116 
2117  if (oldObj) {
2118  _genObjects.Replace(oldObj,wrapper) ;
2119  delete oldObj ;
2120  } else {
2121  _genObjects.Add(wrapper) ;
2122  }
2123  return kFALSE ;
2124 }
2125 
2126 
2127 
2128 
2129 ////////////////////////////////////////////////////////////////////////////////
2130 /// Insert RooStudyManager module
2131 
2133 {
2134  RooAbsStudy* clone = (RooAbsStudy*) study.Clone() ;
2135  _studyMods.Add(clone) ;
2136  return kFALSE ;
2137 }
2138 
2139 
2140 
2141 
2142 ////////////////////////////////////////////////////////////////////////////////
2143 /// Remove all RooStudyManager modules
2144 
2146 {
2147  _studyMods.Delete() ;
2148 }
2149 
2150 
2151 
2152 
2153 ////////////////////////////////////////////////////////////////////////////////
2154 /// Return any type of object (RooAbsArg, RooAbsData or generic object) with given name)
2155 
2156 TObject* RooWorkspace::obj(const char* name) const
2157 {
2158  // Try RooAbsArg first
2159  TObject* ret = arg(name) ;
2160  if (ret) return ret ;
2161 
2162  // Then try RooAbsData
2163  ret = data(name) ;
2164  if (ret) return ret ;
2165 
2166  // Finally try generic object store
2167  return genobj(name) ;
2168 }
2169 
2170 
2171 
2172 ////////////////////////////////////////////////////////////////////////////////
2173 /// Return generic object with given name
2174 
2175 TObject* RooWorkspace::genobj(const char* name) const
2176 {
2177  // Find object by name
2178  TObject* gobj = _genObjects.FindObject(name) ;
2179 
2180  // Exit here if not found
2181  if (!gobj) return 0 ;
2182 
2183  // If found object is wrapper, return payload
2184  if (gobj->IsA()==RooTObjWrap::Class()) return ((RooTObjWrap*)gobj)->obj() ;
2185 
2186  return gobj ;
2187 }
2188 
2189 
2190 
2191 ////////////////////////////////////////////////////////////////////////////////
2192 
2193 Bool_t RooWorkspace::cd(const char* path)
2194 {
2195  makeDir() ;
2196  return _dir->cd(path) ;
2197 }
2198 
2199 
2200 
2201 ////////////////////////////////////////////////////////////////////////////////
2202 /// Save this current workspace into given file
2203 
2204 Bool_t RooWorkspace::writeToFile(const char* fileName, Bool_t recreate)
2205 {
2206  TFile f(fileName,recreate?"RECREATE":"UPDATE") ;
2207  Write() ;
2208  return kFALSE ;
2209 }
2210 
2211 
2212 
2213 ////////////////////////////////////////////////////////////////////////////////
2214 /// Return instance to factory tool
2215 
2217 {
2218  if (_factory) {
2219  return *_factory ;
2220  }
2221  cxcoutD(ObjectHandling) << "INFO: Creating RooFactoryWSTool associated with this workspace" << endl ;
2222  _factory = new RooFactoryWSTool(*this) ;
2223  return *_factory ;
2224 }
2225 
2226 
2227 
2228 
2229 ////////////////////////////////////////////////////////////////////////////////
2230 /// Short-hand function for factory()->process(expr) ;
2231 
2233 {
2234  return factory().process(expr) ;
2235 }
2236 
2237 
2238 
2239 
2240 ////////////////////////////////////////////////////////////////////////////////
2241 /// Print contents of the workspace
2242 
2243 void RooWorkspace::Print(Option_t* opts) const
2244 {
2245  Bool_t treeMode(kFALSE) ;
2246  Bool_t verbose(kFALSE);
2247  if (TString(opts).Contains("t")) {
2248  treeMode=kTRUE ;
2249  }
2250  if (TString(opts).Contains("v")) {
2251  verbose = kTRUE;
2252  }
2253 
2254  cout << endl << "RooWorkspace(" << GetName() << ") " << GetTitle() << " contents" << endl << endl ;
2255 
2256  RooAbsArg* parg ;
2257 
2258  RooArgSet pdfSet ;
2259  RooArgSet funcSet ;
2260  RooArgSet varSet ;
2261  RooArgSet catfuncSet ;
2262  RooArgSet convResoSet ;
2263  RooArgSet resoSet ;
2264 
2265 
2266  // Split list of components in pdfs, functions and variables
2268  while((parg=(RooAbsArg*)iter->Next())) {
2269 
2270  //---------------
2271 
2272  if (treeMode) {
2273 
2274  // In tree mode, only add nodes with no clients to the print lists
2275 
2276  if (parg->IsA()->InheritsFrom(RooAbsPdf::Class())) {
2277  if (!parg->hasClients()) {
2278  pdfSet.add(*parg) ;
2279  }
2280  }
2281 
2282  if (parg->IsA()->InheritsFrom(RooAbsReal::Class()) &&
2283  !parg->IsA()->InheritsFrom(RooAbsPdf::Class()) &&
2284  !parg->IsA()->InheritsFrom(RooConstVar::Class()) &&
2285  !parg->IsA()->InheritsFrom(RooRealVar::Class())) {
2286  if (!parg->hasClients()) {
2287  funcSet.add(*parg) ;
2288  }
2289  }
2290 
2291 
2292  if (parg->IsA()->InheritsFrom(RooAbsCategory::Class()) &&
2293  !parg->IsA()->InheritsFrom(RooCategory::Class())) {
2294  if (!parg->hasClients()) {
2295  catfuncSet.add(*parg) ;
2296  }
2297  }
2298 
2299  } else {
2300 
2301  if (parg->IsA()->InheritsFrom(RooResolutionModel::Class())) {
2302  if (((RooResolutionModel*)parg)->isConvolved()) {
2303  convResoSet.add(*parg) ;
2304  } else {
2305  resoSet.add(*parg) ;
2306  }
2307  }
2308 
2309  if (parg->IsA()->InheritsFrom(RooAbsPdf::Class()) &&
2310  !parg->IsA()->InheritsFrom(RooResolutionModel::Class())) {
2311  pdfSet.add(*parg) ;
2312  }
2313 
2314  if (parg->IsA()->InheritsFrom(RooAbsReal::Class()) &&
2315  !parg->IsA()->InheritsFrom(RooAbsPdf::Class()) &&
2316  !parg->IsA()->InheritsFrom(RooConstVar::Class()) &&
2317  !parg->IsA()->InheritsFrom(RooRealVar::Class())) {
2318  funcSet.add(*parg) ;
2319  }
2320 
2321  if (parg->IsA()->InheritsFrom(RooAbsCategory::Class()) &&
2322  !parg->IsA()->InheritsFrom(RooCategory::Class())) {
2323  catfuncSet.add(*parg) ;
2324  }
2325  }
2326 
2327  if (parg->IsA()->InheritsFrom(RooRealVar::Class())) {
2328  varSet.add(*parg) ;
2329  }
2330 
2331  if (parg->IsA()->InheritsFrom(RooCategory::Class())) {
2332  varSet.add(*parg) ;
2333  }
2334 
2335  }
2336  delete iter ;
2337 
2338 
2341 
2342  if (varSet.getSize()>0) {
2343  varSet.sort() ;
2344  cout << "variables" << endl ;
2345  cout << "---------" << endl ;
2346  cout << varSet << endl ;
2347  cout << endl ;
2348  }
2349 
2350  if (pdfSet.getSize()>0) {
2351  cout << "p.d.f.s" << endl ;
2352  cout << "-------" << endl ;
2353  pdfSet.sort() ;
2354  iter = pdfSet.createIterator() ;
2355  while((parg=(RooAbsArg*)iter->Next())) {
2356  if (treeMode) {
2357  parg->printComponentTree() ;
2358  } else {
2359  parg->Print() ;
2360  }
2361  }
2362  delete iter ;
2363  cout << endl ;
2364  }
2365 
2366  if (!treeMode) {
2367  if (resoSet.getSize()>0) {
2368  cout << "analytical resolution models" << endl ;
2369  cout << "----------------------------" << endl ;
2370  resoSet.sort() ;
2371  iter = resoSet.createIterator() ;
2372  while((parg=(RooAbsArg*)iter->Next())) {
2373  parg->Print() ;
2374  }
2375  delete iter ;
2376  // iter = convResoSet.createIterator() ;
2377  // while((parg=(RooAbsArg*)iter->Next())) {
2378  // parg->Print() ;
2379  // }
2380  // delete iter ;
2381  cout << endl ;
2382  }
2383  }
2384 
2385  if (funcSet.getSize()>0) {
2386  cout << "functions" << endl ;
2387  cout << "--------" << endl ;
2388  funcSet.sort() ;
2389  iter = funcSet.createIterator() ;
2390  while((parg=(RooAbsArg*)iter->Next())) {
2391  if (treeMode) {
2392  parg->printComponentTree() ;
2393  } else {
2394  parg->Print() ;
2395  }
2396  }
2397  delete iter ;
2398  cout << endl ;
2399  }
2400 
2401  if (catfuncSet.getSize()>0) {
2402  cout << "category functions" << endl ;
2403  cout << "------------------" << endl ;
2404  catfuncSet.sort() ;
2405  iter = catfuncSet.createIterator() ;
2406  while((parg=(RooAbsArg*)iter->Next())) {
2407  if (treeMode) {
2408  parg->printComponentTree() ;
2409  } else {
2410  parg->Print() ;
2411  }
2412  }
2413  delete iter ;
2414  cout << endl ;
2415  }
2416 
2417  if (_dataList.GetSize()>0) {
2418  cout << "datasets" << endl ;
2419  cout << "--------" << endl ;
2420  iter = _dataList.MakeIterator() ;
2421  RooAbsData* data2 ;
2422  while((data2=(RooAbsData*)iter->Next())) {
2423  cout << data2->IsA()->GetName() << "::" << data2->GetName() << *data2->get() << endl ;
2424  }
2425  delete iter ;
2426  cout << endl ;
2427  }
2428 
2429  if (_embeddedDataList.GetSize()>0) {
2430  cout << "embedded datasets (in pdfs and functions)" << endl ;
2431  cout << "-----------------------------------------" << endl ;
2432  iter = _embeddedDataList.MakeIterator() ;
2433  RooAbsData* data2 ;
2434  while((data2=(RooAbsData*)iter->Next())) {
2435  cout << data2->IsA()->GetName() << "::" << data2->GetName() << *data2->get() << endl ;
2436  }
2437  delete iter ;
2438  cout << endl ;
2439  }
2440 
2441  if (_snapshots.GetSize()>0) {
2442  cout << "parameter snapshots" << endl ;
2443  cout << "-------------------" << endl ;
2444  iter = _snapshots.MakeIterator() ;
2445  RooArgSet* snap ;
2446  while((snap=(RooArgSet*)iter->Next())) {
2447  cout << snap->GetName() << " = (" ;
2448  TIterator* aiter = snap->createIterator() ;
2449  RooAbsArg* a ;
2450  Bool_t first(kTRUE) ;
2451  while((a=(RooAbsArg*)aiter->Next())) {
2452  if (first) { first=kFALSE ; } else { cout << "," ; }
2453  cout << a->GetName() << "=" ;
2454  a->printValue(cout) ;
2455  if (a->isConstant()) {
2456  cout << "[C]" ;
2457  }
2458  }
2459  cout << ")" << endl ;
2460  delete aiter ;
2461  }
2462  delete iter ;
2463  cout << endl ;
2464  }
2465 
2466 
2467  if (_namedSets.size()>0) {
2468  cout << "named sets" << endl ;
2469  cout << "----------" << endl ;
2470  for (map<string,RooArgSet>::const_iterator it = _namedSets.begin() ; it != _namedSets.end() ; it++) {
2471  if (verbose || !TString(it->first.c_str()).BeginsWith("CACHE_")) {
2472  cout << it->first << ":" << it->second << endl;
2473  }
2474  }
2475 
2476  cout << endl ;
2477  }
2478 
2479 
2480  if (_genObjects.GetSize()>0) {
2481  cout << "generic objects" << endl ;
2482  cout << "---------------" << endl ;
2483  iter = _genObjects.MakeIterator() ;
2484  TObject* gobj ;
2485  while((gobj=(TObject*)iter->Next())) {
2486  if (gobj->IsA()==RooTObjWrap::Class()) {
2487  cout << ((RooTObjWrap*)gobj)->obj()->IsA()->GetName() << "::" << gobj->GetName() << endl ;
2488  } else {
2489  cout << gobj->IsA()->GetName() << "::" << gobj->GetName() << endl ;
2490  }
2491  }
2492  delete iter ;
2493  cout << endl ;
2494 
2495  }
2496 
2497  if (_studyMods.GetSize()>0) {
2498  cout << "study modules" << endl ;
2499  cout << "-------------" << endl ;
2500  iter = _studyMods.MakeIterator() ;
2501  TObject* smobj ;
2502  while((smobj=(TObject*)iter->Next())) {
2503  cout << smobj->IsA()->GetName() << "::" << smobj->GetName() << endl ;
2504  }
2505  delete iter ;
2506  cout << endl ;
2507 
2508  }
2509 
2510  if (_classes.listOfClassNames().size()>0) {
2511  cout << "embedded class code" << endl ;
2512  cout << "-------------------" << endl ;
2513  cout << _classes.listOfClassNames() << endl ;
2514  cout << endl ;
2515  }
2516 
2517  if (_eocache.size()>0) {
2518  cout << "embedded precalculated expensive components" << endl ;
2519  cout << "-------------------------------------------" << endl ;
2520  _eocache.print() ;
2521  }
2522 
2524 
2525  return ;
2526 }
2527 
2528 
2529 ////////////////////////////////////////////////////////////////////////////////
2530 /// Custom streamer for the workspace. Stream contents of workspace
2531 /// and code repository. When reading, read code repository first
2532 /// and compile missing classes before proceeding with streaming
2533 /// of workspace contents to avoid errors.
2534 
2535 void RooWorkspace::CodeRepo::Streamer(TBuffer &R__b)
2536 {
2537  typedef ::RooWorkspace::CodeRepo thisClass;
2538 
2539  // Stream an object of class RooWorkspace::CodeRepo.
2540  if (R__b.IsReading()) {
2541 
2542  UInt_t R__s, R__c;
2543  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2544 
2545  // Stream contents of ClassFiles map
2546  Int_t count(0) ;
2547  R__b >> count ;
2548  while(count--) {
2549  TString name ;
2550  name.Streamer(R__b) ;
2551  _fmap[name]._hext.Streamer(R__b) ;
2552  _fmap[name]._hfile.Streamer(R__b) ;
2553  _fmap[name]._cxxfile.Streamer(R__b) ;
2554  }
2555 
2556  // Stream contents of ClassRelInfo map
2557  count=0 ;
2558  R__b >> count ;
2559  while(count--) {
2560  TString name ;
2561  name.Streamer(R__b) ;
2562  _c2fmap[name]._baseName.Streamer(R__b) ;
2563  _c2fmap[name]._fileBase.Streamer(R__b) ;
2564  }
2565 
2566  if (R__v==2) {
2567 
2568  count=0 ;
2569  R__b >> count ;
2570  while(count--) {
2571  TString name ;
2572  name.Streamer(R__b) ;
2573  _ehmap[name]._hname.Streamer(R__b) ;
2574  _ehmap[name]._hfile.Streamer(R__b) ;
2575  }
2576  }
2577 
2578  R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
2579 
2580  // Instantiate any classes that are not defined in current session
2581  _compiledOK = !compileClasses() ;
2582 
2583  } else {
2584 
2585  UInt_t R__c;
2586  R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
2587 
2588  // Stream contents of ClassFiles map
2589  UInt_t count = _fmap.size() ;
2590  R__b << count ;
2591  map<TString,ClassFiles>::iterator iter = _fmap.begin() ;
2592  while(iter!=_fmap.end()) {
2593  TString key_copy(iter->first) ;
2594  key_copy.Streamer(R__b) ;
2595  iter->second._hext.Streamer(R__b) ;
2596  iter->second._hfile.Streamer(R__b);
2597  iter->second._cxxfile.Streamer(R__b);
2598 
2599  ++iter ;
2600  }
2601 
2602  // Stream contents of ClassRelInfo map
2603  count = _c2fmap.size() ;
2604  R__b << count ;
2605  map<TString,ClassRelInfo>::iterator iter2 = _c2fmap.begin() ;
2606  while(iter2!=_c2fmap.end()) {
2607  TString key_copy(iter2->first) ;
2608  key_copy.Streamer(R__b) ;
2609  iter2->second._baseName.Streamer(R__b) ;
2610  iter2->second._fileBase.Streamer(R__b);
2611  ++iter2 ;
2612  }
2613 
2614  // Stream contents of ExtraHeader map
2615  count = _ehmap.size() ;
2616  R__b << count ;
2617  map<TString,ExtraHeader>::iterator iter3 = _ehmap.begin() ;
2618  while(iter3!=_ehmap.end()) {
2619  TString key_copy(iter3->first) ;
2620  key_copy.Streamer(R__b) ;
2621  iter3->second._hname.Streamer(R__b) ;
2622  iter3->second._hfile.Streamer(R__b);
2623  ++iter3 ;
2624  }
2625 
2626  R__b.SetByteCount(R__c, kTRUE);
2627 
2628  }
2629 }
2630 
2631 
2632 ////////////////////////////////////////////////////////////////////////////////
2633 /// Stream an object of class RooWorkspace. This is a standard ROOT streamer for the
2634 /// I/O part. This custom function exists to detach all external client links
2635 /// from the payload prior to writing the payload so that these client links
2636 /// are not persisted. (Client links occur if external function objects use
2637 /// objects contained in the workspace as input)
2638 /// After the actual writing, these client links are restored.
2639 
2640 void RooWorkspace::Streamer(TBuffer &R__b)
2641 {
2642  if (R__b.IsReading()) {
2643 
2644  R__b.ReadClassBuffer(RooWorkspace::Class(),this);
2645 
2646  // Perform any pass-2 schema evolution here
2647  RooFIter fiter = _allOwnedNodes.fwdIterator() ;
2648  RooAbsArg* node ;
2649  while((node=fiter.next())) {
2650  node->ioStreamerPass2() ;
2651  }
2653 
2654  // Make expensive object cache of all objects point to intermal copy.
2655  // Somehow this doesn't work OK automatically
2657  while((node=(RooAbsArg*)iter->Next())) {
2659  node->setWorkspace(*this);
2660  if (node->IsA()->InheritsFrom(RooAbsOptTestStatistic::Class())) {
2662  if (tmp->isSealed() && tmp->sealNotice() && strlen(tmp->sealNotice()) > 0) {
2663  cout << "RooWorkspace::Streamer(" << GetName() << ") " << node->IsA()->GetName() << "::" << node->GetName()
2664  << " : " << tmp->sealNotice() << endl;
2665  }
2666  }
2667  }
2668  delete iter ;
2669 
2670 
2671  } else {
2672 
2673  // Make lists of external clients of WS objects, and remove those links temporarily
2674 
2675  map<RooAbsArg*,list<RooAbsArg*> > extClients, extValueClients, extShapeClients ;
2676 
2678  RooAbsArg* tmparg ;
2679  while((tmparg=(RooAbsArg*)iter->Next())) {
2680 
2681  // Loop over client list of this arg
2682  TIterator* clientIter = tmparg->_clientList.MakeIterator() ;
2683  RooAbsArg* client ;
2684  while((client=(RooAbsArg*)clientIter->Next())) {
2685  if (!_allOwnedNodes.containsInstance(*client)) {
2686  while(tmparg->_clientList.refCount(client)>0) {
2687  tmparg->_clientList.Remove(client) ;
2688  extClients[tmparg].push_back(client) ;
2689  }
2690  }
2691  }
2692  delete clientIter ;
2693 
2694  // Loop over value client list of this arg
2695  TIterator* vclientIter = tmparg->_clientListValue.MakeIterator() ;
2696  RooAbsArg* vclient ;
2697  while((vclient=(RooAbsArg*)vclientIter->Next())) {
2698  if (!_allOwnedNodes.containsInstance(*vclient)) {
2699  cxcoutD(ObjectHandling) << "RooWorkspace::Streamer(" << GetName() << ") element " << tmparg->GetName()
2700  << " has external value client link to " << vclient << " (" << vclient->GetName() << ") with ref count " << tmparg->_clientListValue.refCount(vclient) << endl ;
2701  while(tmparg->_clientListValue.refCount(vclient)>0) {
2702  tmparg->_clientListValue.Remove(vclient) ;
2703  extValueClients[tmparg].push_back(vclient) ;
2704  }
2705  }
2706  }
2707  delete vclientIter ;
2708 
2709  // Loop over shape client list of this arg
2710  TIterator* sclientIter = tmparg->_clientListShape.MakeIterator() ;
2711  RooAbsArg* sclient ;
2712  while((sclient=(RooAbsArg*)sclientIter->Next())) {
2713  if (!_allOwnedNodes.containsInstance(*sclient)) {
2714  cxcoutD(ObjectHandling) << "RooWorkspace::Streamer(" << GetName() << ") element " << tmparg->GetName()
2715  << " has external shape client link to " << sclient << " (" << sclient->GetName() << ") with ref count " << tmparg->_clientListShape.refCount(sclient) << endl ;
2716  while(tmparg->_clientListShape.refCount(sclient)>0) {
2717  tmparg->_clientListShape.Remove(sclient) ;
2718  extShapeClients[tmparg].push_back(sclient) ;
2719  }
2720  }
2721  }
2722  delete sclientIter ;
2723 
2724  }
2725  delete iter ;
2726 
2728 
2729  // Reinstate clients here
2730 
2731 
2732  for (map<RooAbsArg*,list<RooAbsArg*> >::iterator iterx = extClients.begin() ; iterx!=extClients.end() ; iterx++) {
2733  for (list<RooAbsArg*>::iterator citer = iterx->second.begin() ; citer!=iterx->second.end() ; citer++) {
2734  iterx->first->_clientList.Add(*citer) ;
2735  }
2736  }
2737 
2738  for (map<RooAbsArg*,list<RooAbsArg*> >::iterator iterx = extValueClients.begin() ; iterx!=extValueClients.end() ; iterx++) {
2739  for (list<RooAbsArg*>::iterator citer = iterx->second.begin() ; citer!=iterx->second.end() ; citer++) {
2740  iterx->first->_clientListValue.Add(*citer) ;
2741  }
2742  }
2743 
2744  for (map<RooAbsArg*,list<RooAbsArg*> >::iterator iterx = extShapeClients.begin() ; iterx!=extShapeClients.end() ; iterx++) {
2745  for (list<RooAbsArg*>::iterator citer = iterx->second.begin() ; citer!=iterx->second.end() ; citer++) {
2746  iterx->first->_clientListShape.Add(*citer) ;
2747  }
2748  }
2749 
2750  }
2751 }
2752 
2753 
2754 
2755 
2756 ////////////////////////////////////////////////////////////////////////////////
2757 /// Return STL string with last of class names contained in the code repository
2758 
2760 {
2761  string ret ;
2762  map<TString,ClassRelInfo>::const_iterator iter = _c2fmap.begin() ;
2763  while(iter!=_c2fmap.end()) {
2764  if (ret.size()>0) {
2765  ret += ", " ;
2766  }
2767  ret += iter->first ;
2768  ++iter ;
2769  }
2770 
2771  return ret ;
2772 }
2773 
2774 
2775 
2776 ////////////////////////////////////////////////////////////////////////////////
2777 /// For all classes in the workspace for which no class definition is
2778 /// found in the ROOT class table extract source code stored in code
2779 /// repository into temporary directory set by
2780 /// setClassFileExportDir(), compile classes and link them with
2781 /// current ROOT session. If a compilation error occurs print
2782 /// instructions for user how to fix errors and recover workspace and
2783 /// abort import procedure.
2784 
2786 {
2787  Bool_t haveDir=kFALSE ;
2788 
2789  // Retrieve name of directory in which to export code files
2790  string dirName = Form(_classFileExportDir.c_str(),_wspace->uuid().AsString(),_wspace->GetName()) ;
2791 
2792  Bool_t writeExtraHeaders(kFALSE) ;
2793 
2794  // Process all class entries in repository
2795  map<TString,ClassRelInfo>::iterator iter = _c2fmap.begin() ;
2796  while(iter!=_c2fmap.end()) {
2797 
2798  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() now processing class " << iter->first.Data() << endl ;
2799 
2800  // If class is already known, don't load
2801  if (gClassTable->GetDict(iter->first.Data())) {
2802  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() Embedded class "
2803  << iter->first << " already in ROOT class table, skipping" << endl ;
2804  ++iter ;
2805  continue ;
2806  }
2807 
2808  // Check that export directory exists
2809  if (!haveDir) {
2810 
2811  // If not, make local directory to extract files
2812  if (!gSystem->AccessPathName(dirName.c_str())) {
2813  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() reusing code export directory " << dirName.c_str()
2814  << " to extract coded embedded in workspace" << endl ;
2815  } else {
2816  if (gSystem->MakeDirectory(dirName.c_str())==0) {
2817  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() creating code export directory " << dirName.c_str()
2818  << " to extract coded embedded in workspace" << endl ;
2819  } else {
2820  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() ERROR creating code export directory " << dirName.c_str()
2821  << " to extract coded embedded in workspace" << endl ;
2822  return kFALSE ;
2823  }
2824  }
2825  haveDir=kTRUE ;
2826 
2827  }
2828 
2829  // First write any extra header files
2830  if (!writeExtraHeaders) {
2831  writeExtraHeaders = kTRUE ;
2832 
2833  map<TString,ExtraHeader>::iterator eiter = _ehmap.begin() ;
2834  while(eiter!=_ehmap.end()) {
2835 
2836  // Check if identical declaration file (header) is already written
2837  Bool_t needEHWrite=kTRUE ;
2838  string fdname = Form("%s/%s",dirName.c_str(),eiter->second._hname.Data()) ;
2839  ifstream ifdecl(fdname.c_str()) ;
2840  if (ifdecl) {
2841  TString contents ;
2842  char buf[64000];
2843  while (ifdecl.getline(buf, 64000)) {
2844  contents += buf;
2845  contents += "\n";
2846  }
2847  UInt_t crcFile = RooAbsArg::crc32(contents.Data());
2848  UInt_t crcWS = RooAbsArg::crc32(eiter->second._hfile.Data());
2849  needEHWrite = (crcFile != crcWS);
2850  }
2851 
2852  // Write declaration file if required
2853  if (needEHWrite) {
2854  oocoutI(_wspace, ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() Extracting extra header file "
2855  << fdname << endl;
2856 
2857  // Extra headers may contain non-existing path - create first to be sure
2858  gSystem->MakeDirectory(gSystem->DirName(fdname.c_str()));
2859 
2860  ofstream fdecl(fdname.c_str());
2861  if (!fdecl) {
2862  oocoutE(_wspace, ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() ERROR opening file " << fdname
2863  << " for writing" << endl;
2864  return kFALSE;
2865  }
2866  fdecl << eiter->second._hfile.Data();
2867  fdecl.close();
2868  }
2869  eiter++;
2870  }
2871  }
2872 
2873 
2874  // Navigate from class to file
2875  ClassFiles& cfinfo = _fmap[iter->second._fileBase] ;
2876 
2877  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() now processing file with base " << iter->second._fileBase << endl ;
2878 
2879  // If file is already processed, skip to next class
2880  if (cfinfo._extracted) {
2881  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() file with base name " << iter->second._fileBase
2882  << " has already been extracted, skipping to next class" << endl ;
2883  continue ;
2884  }
2885 
2886  // Check if identical declaration file (header) is already written
2887  Bool_t needDeclWrite=kTRUE ;
2888  string fdname = Form("%s/%s.%s",dirName.c_str(),iter->second._fileBase.Data(),cfinfo._hext.Data()) ;
2889  ifstream ifdecl(fdname.c_str()) ;
2890  if (ifdecl) {
2891  TString contents ;
2892  char buf[64000];
2893  while (ifdecl.getline(buf, 64000)) {
2894  contents += buf;
2895  contents += "\n";
2896  }
2897  UInt_t crcFile = RooAbsArg::crc32(contents.Data()) ;
2898  UInt_t crcWS = RooAbsArg::crc32(cfinfo._hfile.Data()) ;
2899  needDeclWrite = (crcFile!=crcWS) ;
2900  }
2901 
2902  // Write declaration file if required
2903  if (needDeclWrite) {
2904  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() Extracting declaration code of class " << iter->first << ", file " << fdname << endl ;
2905  ofstream fdecl(fdname.c_str()) ;
2906  if (!fdecl) {
2907  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() ERROR opening file "
2908  << fdname << " for writing" << endl ;
2909  return kFALSE ;
2910  }
2911  fdecl << cfinfo._hfile ;
2912  fdecl.close() ;
2913  }
2914 
2915  // Check if identical implementation file is already written
2916  Bool_t needImplWrite=kTRUE ;
2917  string finame = Form("%s/%s.cxx",dirName.c_str(),iter->second._fileBase.Data()) ;
2918  ifstream ifimpl(finame.c_str()) ;
2919  if (ifimpl) {
2920  TString contents ;
2921  char buf[64000];
2922  while (ifimpl.getline(buf, 64000)) {
2923  contents += buf;
2924  contents += "\n";
2925  }
2926  UInt_t crcFile = RooAbsArg::crc32(contents.Data()) ;
2927  UInt_t crcWS = RooAbsArg::crc32(cfinfo._cxxfile.Data()) ;
2928  needImplWrite = (crcFile!=crcWS) ;
2929  }
2930 
2931  // Write implementation file if required
2932  if (needImplWrite) {
2933  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() Extracting implementation code of class " << iter->first << ", file " << finame << endl ;
2934  ofstream fimpl(finame.c_str()) ;
2935  if (!fimpl) {
2936  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() ERROR opening file"
2937  << finame << " for writing" << endl ;
2938  return kFALSE ;
2939  }
2940  fimpl << cfinfo._cxxfile ;
2941  fimpl.close() ;
2942  }
2943 
2944  // Mark this file as extracted
2945  cfinfo._extracted = kTRUE ;
2946  oocxcoutD(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() marking code unit " << iter->second._fileBase << " as extracted" << endl ;
2947 
2948  // Compile class
2949  oocoutI(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() Compiling code unit " << iter->second._fileBase.Data() << " to define class " << iter->first << endl ;
2950  Bool_t ok = gSystem->CompileMacro(finame.c_str(),"k") ;
2951 
2952  if (!ok) {
2953  oocoutE(_wspace,ObjectHandling) << "RooWorkspace::CodeRepo::compileClasses() ERROR compiling class " << iter->first.Data() << ", to fix this you can do the following: " << endl
2954  << " 1) Fix extracted source code files in directory " << dirName.c_str() << "/" << endl
2955  << " 2) In clean ROOT session compiled fixed classes by hand using '.x " << dirName.c_str() << "/ClassName.cxx+'" << endl
2956  << " 3) Reopen file with RooWorkspace with broken source code in UPDATE mode. Access RooWorkspace to force loading of class" << endl
2957  << " Broken instances in workspace will _not_ be compiled, instead precompiled fixed instances will be used." << endl
2958  << " 4) Reimport fixed code in workspace using 'RooWorkspace::importClassCode(\"*\",kTRUE)' method, Write() updated workspace to file and close file" << endl
2959  << " 5) Reopen file in clean ROOT session to confirm that problems are fixed" << endl ;
2960  return kFALSE ;
2961  }
2962 
2963  ++iter ;
2964  }
2965 
2966  return kTRUE ;
2967 }
2968 
2969 
2970 
2971 ////////////////////////////////////////////////////////////////////////////////
2972 /// Internal access to TDirectory append method
2973 
2975 {
2976 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,19,02)
2977  TDirectory::Append(obj) ;
2978 #else
2979  TDirectory::Append(obj,kFALSE) ;
2980 #endif
2981 
2982 }
2983 
2984 
2985 ////////////////////////////////////////////////////////////////////////////////
2986 /// Overload TDirectory interface method to prohibit insertion of objects in read-only directory workspace representation
2987 
2988 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,19,02)
2990 #else
2992 #endif
2993 {
2994  if (dynamic_cast<RooAbsArg*>(obj) || dynamic_cast<RooAbsData*>(obj)) {
2995  coutE(ObjectHandling) << "RooWorkspace::WSDir::Add(" << GetName() << ") ERROR: Directory is read-only representation of a RooWorkspace, use RooWorkspace::import() to add objects" << endl ;
2996  } else {
2997  InternalAppend(obj) ;
2998  }
2999 }
3000 
3001 
3002 ////////////////////////////////////////////////////////////////////////////////
3003 /// Overload TDirectory interface method to prohibit insertion of objects in read-only directory workspace representation
3004 
3005 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,19,02)
3007 #else
3009 #endif
3010 {
3011  if (dynamic_cast<RooAbsArg*>(obj) || dynamic_cast<RooAbsData*>(obj)) {
3012  coutE(ObjectHandling) << "RooWorkspace::WSDir::Add(" << GetName() << ") ERROR: Directory is read-only representation of a RooWorkspace, use RooWorkspace::import() to add objects" << endl ;
3013  } else {
3014  InternalAppend(obj) ;
3015  }
3016 }
3017 
3018 
3019 
3020 ////////////////////////////////////////////////////////////////////////////////
3021 /// Activate export of workspace symbols to CINT in a namespace with given name. If no name
3022 /// is given the namespace will have the same name as the workspace
3023 
3024 void RooWorkspace::exportToCint(const char* nsname)
3025 {
3026  // If export is already active, do nothing
3027  if (_doExport) {
3028  coutE(ObjectHandling) << "RooWorkspace::exportToCint(" << GetName() << ") WARNING: repeated calls to exportToCint() have no effect" << endl ;
3029  return ;
3030  }
3031 
3032  // Set flag so that future import to workspace are automatically exported to CINT
3033  _doExport = kTRUE ;
3034 
3035  // If no name is provided choose name of workspace
3036  if (!nsname) nsname = GetName() ;
3037  _exportNSName = nsname ;
3038 
3039  coutI(ObjectHandling) << "RooWorkspace::exportToCint(" << GetName()
3040  << ") INFO: references to all objects in this workspace will be created in CINT in 'namespace " << _exportNSName << "'" << endl ;
3041 
3042  // Export present contents of workspace to CINT
3044  TObject* wobj ;
3045  while((wobj=iter->Next())) {
3046  exportObj(wobj) ;
3047  }
3048  delete iter ;
3049  iter = _dataList.MakeIterator() ;
3050  while((wobj=iter->Next())) {
3051  exportObj(wobj) ;
3052  }
3053  delete iter ;
3054 }
3055 
3056 
3057 ////////////////////////////////////////////////////////////////////////////////
3058 /// Export reference to given workspace object to CINT
3059 
3061 {
3062  // Do nothing if export flag is not set
3063  if (!_doExport) return ;
3064 
3065  // Do not export RooConstVars
3066  if (wobj->IsA() == RooConstVar::Class()) {
3067  return ;
3068  }
3069 
3070 
3071  // Determine if object name is a valid C++ identifier name
3072 
3073  // Do not export objects that have names that are not valid C++ identifiers
3074  if (!isValidCPPID(wobj->GetName())) {
3075  cxcoutD(ObjectHandling) << "RooWorkspace::exportObj(" << GetName() << ") INFO: Workspace object name " << wobj->GetName() << " is not a valid C++ identifier and is not exported to CINT" << endl ;
3076  return ;
3077  }
3078 
3079  // Declare correctly typed reference to object in CINT in the namespace associated with this workspace
3080  string cintExpr = Form("namespace %s { %s& %s = *(%s *)0x%lx ; }",_exportNSName.c_str(),wobj->IsA()->GetName(),wobj->GetName(),wobj->IsA()->GetName(),(ULong_t)wobj) ;
3081  gROOT->ProcessLine(cintExpr.c_str()) ;
3082 }
3083 
3084 
3085 
3086 ////////////////////////////////////////////////////////////////////////////////
3087 /// Return true if given name is a valid C++ identifier name
3088 
3090 {
3091  string oname(name) ;
3092  if (isdigit(oname[0])) {
3093  return kFALSE ;
3094  } else {
3095  for (UInt_t i=0 ; i<oname.size() ; i++) {
3096  char c = oname[i] ;
3097  if (!isalnum(c) && (c!='_')) {
3098  return kFALSE ;
3099  }
3100  }
3101  }
3102  return kTRUE ;
3103 }
3104 
3105 ////////////////////////////////////////////////////////////////////////////////
3106 /// Delete exported reference in CINT namespace
3107 
3109 {
3110  char buf[64000];
3112  TObject *wobj;
3113  while ((wobj = iter->Next())) {
3114  if (isValidCPPID(wobj->GetName())) {
3115  strlcpy(buf, Form("%s::%s", _exportNSName.c_str(), wobj->GetName()), 64000);
3116  gInterpreter->DeleteVariable(buf);
3117  }
3118  }
3119  delete iter ;
3120 }
3121 
3122 ////////////////////////////////////////////////////////////////////////////////
3123 /// If one of the TObject we have a referenced to is deleted, remove the
3124 /// reference.
3125 
3127 {
3128  _dataList.RecursiveRemove(removedObj);
3129  if (removedObj == _dir) _dir = nullptr;
3130 
3131  _allOwnedNodes.RecursiveRemove(removedObj); // RooArgSet
3132 
3133  _dataList.RecursiveRemove(removedObj);
3134  _embeddedDataList.RecursiveRemove(removedObj);
3135  _views.RecursiveRemove(removedObj);
3136  _snapshots.RecursiveRemove(removedObj);
3137  _genObjects.RecursiveRemove(removedObj);
3138  _studyMods.RecursiveRemove(removedObj);
3139 
3140  for(auto c : _namedSets) {
3141  c.second.RecursiveRemove(removedObj);
3142  }
3143 
3144  _eocache.RecursiveRemove(removedObj); // RooExpensiveObjectCache
3145 }
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:243
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2078
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:932
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1276
Bool_t saveSnapshot(const char *name, const char *paramNames)
Save snapshot of values and attributes (including "Constant") of parameters &#39;params&#39; If importValues ...
Bool_t IsReading() const
Definition: TBuffer.h:83
TIterator * createIterator(Bool_t dir=kIterForward) const
RooArgSet allCatFunctions() const
Return set with all category function objects.
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3507
#define coutE(a)
Definition: RooMsgService.h:34
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:86
static Bool_t _autoClass
Definition: RooWorkspace.h:256
RooExpensiveObjectCache _eocache
Transient ROOT directory representation of workspace.
Definition: RooWorkspace.h:271
const char * GetDeclFileName() const
Definition: TClass.h:395
void sort(Bool_t ascend=kTRUE)
virtual void Reset()=0
void exportToCint(const char *namespaceName=0)
Activate export of workspace symbols to CINT in a namespace with given name.
std::list< RooAbsData * > allEmbeddedData() const
Return list of all dataset in the workspace.
short Version_t
Definition: RtypesCore.h:61
static void ioStreamerPass2Finalize()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
Definition: RooAbsArg.cxx:2471
const char * GetImplFileName() const
Definition: TClass.h:421
virtual const RooArgSet * get() const
Definition: RooAbsData.h:79
virtual Bool_t Remove(TObject *arg)
Remove object from collection.
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:95
RooLinkedList _dataList
Definition: RooWorkspace.h:261
RooAbsCategory * catfunc(const char *name) const
Retrieve discrete function (RooAbsCategory) with given name. A null pointer is returned if not found...
const char Option_t
Definition: RtypesCore.h:62
RooAbsCollection * selectCommon(const RooAbsCollection &refColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
static std::list< std::string > _classDeclDirList
Definition: RooWorkspace.h:250
#define coutI(a)
Definition: RooMsgService.h:31
RooExpensiveObjectCache is a singleton class that serves as repository for objects that are expensive...
const char * getString(const char *name, const char *defaultValue="", Bool_t convEmptyToNull=kFALSE)
Return string property registered with name &#39;name&#39;.
#define cxcoutD(a)
Definition: RooMsgService.h:79
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:63
virtual void Append(TObject *)
Overload TDirectory interface method to prohibit insertion of objects in read-only directory workspac...
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
RooLinkedList _embeddedDataList
Definition: RooWorkspace.h:262
Bool_t cancelTransaction()
Cancel an ongoing import transaction.
virtual Bool_t changeObservableName(const char *from, const char *to)
Definition: RooAbsData.cxx:265
RooFactoryWSTool is a clase like TTree::MakeClass() that generates skeleton code for RooAbsPdf and Ro...
TObject * find(const char *name) const
Return pointer to object with given name in collection.
#define oocoutI(o, a)
Definition: RooMsgService.h:44
~RooWorkspace()
Workspace destructor.
RooFactoryWSTool * _factory
Definition: RooWorkspace.h:273
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:825
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
TIterator * componentIterator() const
Definition: RooWorkspace.h:112
Regular expression class.
Definition: TRegexp.h:31
RooFit::MsgLevel globalKillBelow() const
RooAbsData * embeddedData(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found...
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:402
Int_t refCount(TObject *obj)
Return reference count associated with &#39;obj&#39;.
virtual void printValue(std::ostream &os) const
Interface to print value of object.
RooAbsReal * function(const char *name) const
Retrieve function (RooAbsReal) with given name. Note that all RooAbsPdfs are also RooAbsReals...
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1004
bool Bool_t
Definition: RtypesCore.h:59
RooAbsArg * fundArg(const char *name) const
Return fundamental (i.e.
RooArgSet _allOwnedNodes
Definition: RooWorkspace.h:260
static void addClassImplImportDir(const char *dir)
Add &#39;dir&#39; to search path for class implementation (.cxx) files, when attempting to import class code ...
#define gInterpreter
Definition: TInterpreter.h:526
TObject * genobj(const char *name) const
Return generic object with given name.
static std::list< std::string > _classImplDirList
Definition: RooWorkspace.h:251
RooAbsArg * arg(const char *name) const
Return RooAbsArg with given name. A null pointer is returned if none is found.
static RooMsgService & instance()
Return reference to singleton instance.
STL namespace.
Bool_t compileClasses()
For all classes in the workspace for which no class definition is found in the ROOT class table extra...
#define coutW(a)
Definition: RooMsgService.h:33
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
static void autoImportClassCode(Bool_t flag)
If flag is true, source code of classes not the the ROOT distribution is automatically imported if on...
#define ooccoutW(o, a)
Definition: RooMsgService.h:53
RooLinkedList _genObjects
Definition: RooWorkspace.h:265
Bool_t cd(const char *path=0)
RooArgSet argSet(const char *nameList) const
Return set of RooAbsArgs matching to given list of names.
Int_t GetSize() const
Definition: RooLinkedList.h:60
Iterator abstract base class.
Definition: TIterator.h:30
const char * sealNotice() const
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1225
Bool_t Replace(const TObject *oldArg, const TObject *newArg)
Replace object &#39;oldArg&#39; in collection with new object &#39;newArg&#39;.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3950
Bool_t importClassCode(const char *pat="*", Bool_t doReplace=kFALSE)
Inport code of all classes in the workspace that have a class name that matches pattern &#39;pat&#39; and whi...
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TObject.cxx:572
RooRefCountList _clientListValue
Definition: RooAbsArg.h:478
virtual void RecursiveRemove(TObject *obj)
If one of the TObject we have a referenced to is deleted, remove the reference.
Bool_t process(const RooCmdArg &arg)
Process given RooCmdArg.
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string &#39;value&#39; to this object under key &#39;key&#39;.
Definition: RooAbsArg.cxx:275
RooAbsArg * process(const char *expr)
Process high-level object creation syntax Accepted forms of syntax are.
Bool_t startTransaction()
Open an import transaction operations.
void Class()
Definition: Class.C:29
void unExport()
Delete exported reference in CINT namespace.
RooArgSet allFunctions() const
Return set with all function objects.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
void setWorkspace(RooWorkspace &ws)
Definition: RooAbsArg.h:418
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
#define oocoutE(o, a)
Definition: RooMsgService.h:47
Bool_t extendSet(const char *name, const char *newContents)
Define a named set in the work space through a comma separated list of names of objects already in th...
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename"...
Definition: TSystem.cxx:2864
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1638
Bool_t defineString(const char *name, const char *argName, Int_t stringNum, const char *defValue="", Bool_t appendMode=kFALSE)
Define Double_t property name &#39;name&#39; mapped to Double_t in slot &#39;stringNum&#39; in RooCmdArg with name ar...
#define oocxcoutD(o, a)
Definition: RooMsgService.h:81
RooWorkspace()
Default constructor.
RooCategory * cat(const char *name) const
Retrieve discrete variable (RooCategory) with given name. A null pointer is returned if not found...
const RooArgSet * getSnapshot(const char *name) const
Return the RooArgSet containgin a snapshot of variables contained in the workspace.
RooLinkedList _studyMods
Definition: RooWorkspace.h:266
std::list< RooAbsData * > allData() const
Return list of all dataset in the workspace.
Bool_t defineInt(const char *name, const char *argName, Int_t intNum, Int_t defValue=0)
Define integer property name &#39;name&#39; mapped to integer in slot &#39;intNum&#39; in RooCmdArg with name argName...
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const
Return a list iterator.
Definition: TList.cxx:718
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
A doubly linked list.
Definition: TList.h:44
virtual Bool_t isFundamental() const
Definition: RooAbsArg.h:157
RooAbsStudy is an abstract base class for RooStudyManager modules.
Definition: RooAbsStudy.h:33
RooAbsData * data(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found...
virtual void Add(TObject *)
Overload TDirectory interface method to prohibit insertion of objects in read-only directory workspac...
void importCacheObjects(RooExpensiveObjectCache &other, const char *ownerName, Bool_t verbose=kFALSE)
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:266
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
Bool_t autoImportClass(TClass *tc, Bool_t doReplace=kFALSE)
Import code of class &#39;tc&#39; into the repository.
virtual Bool_t importWorkspaceHook(RooWorkspace &ws)
Definition: RooAbsArg.h:501
Int_t getSize() const
void defineMutex(const char *argName1, const char *argName2)
Define arguments named argName1 and argName2 mutually exclusive.
Int_t getInt(const char *name, Int_t defaultValue=0)
Return integer property registered with name &#39;name&#39;.
RooAbsCollection * snapshot(Bool_t deepCopy=kTRUE) const
Take a snap shot of current collection contents: An owning collection is returned containing clones o...
Bool_t renameSet(const char *name, const char *newName)
Rename set to a new name.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2338
SVector< double, 2 > v
Definition: Dict.h:5
RooLinkedList _views
Definition: RooWorkspace.h:263
virtual void RecursiveRemove(TObject *obj)
If one of the TObject we have a referenced to is deleted, remove the reference.
auto * a
Definition: textangle.C:12
Bool_t HasDefaultConstructor() const
Bool_t ok(Bool_t verbose) const
Return true of parsing was successful.
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node...
Definition: RooAbsArg.cxx:481
Bool_t defineSet(const char *name, const RooArgSet &aset, Bool_t importMissing=kFALSE)
Define a named RooArgSet with given constituents.
WSDir * _dir
Definition: RooWorkspace.h:269
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
void printComponentTree(const char *indent="", const char *namePat=0, Int_t nLevel=999)
Print tree structure of expression tree on given ostream, only branch nodes are printed.
Definition: RooAbsArg.cxx:1841
RooArgSet _sandboxNodes
Is there a transaction open?
Definition: RooWorkspace.h:279
unsigned int UInt_t
Definition: RtypesCore.h:42
void SetName(const char *name)
Set the name of the TNamed.
Definition: RooAbsArg.cxx:2386
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key &#39;key&#39;.
Definition: RooAbsArg.cxx:290
char * Form(const char *fmt,...)
RooRefCountList _clientList
Definition: RooAbsArg.h:476
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:190
static UInt_t crc32(const char *data)
Definition: RooAbsArg.cxx:1902
virtual Bool_t addOwned(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling addOwned() for each element in the source...
Definition: RooArgSet.h:90
CodeRepo _classes
Definition: RooWorkspace.h:258
void setGlobalKillBelow(RooFit::MsgLevel level)
Bool_t writeToFile(const char *fileName, Bool_t recreate=kTRUE)
Save this current workspace into given file.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
Bool_t loadSnapshot(const char *name)
Load the values and attributes of the parameters in the snapshot saved with the given name...
RooRefCountList _clientListShape
Definition: RooAbsArg.h:477
RooArgSet allVars() const
Return set with all variable objects.
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5768
RooCategory represents a fundamental (non-derived) discrete value object.
Definition: RooCategory.h:24
Bool_t _openTrans
Name of CINT namespace to which contents are exported.
Definition: RooWorkspace.h:278
std::list< TObject * > allGenericObjects() const
Return list of all generic objects in the workspace.
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:33
TObject * obj(const char *name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name) ...
RooAbsArg * next()
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Bool_t Remove(TObject *obj)
Remove object from list and if reference count reaches zero delete object itself as well...
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t isValidCPPID(const char *name)
Return true if given name is a valid C++ identifier name.
virtual void setExpensiveObjectCache(RooExpensiveObjectCache &cache)
Definition: RooAbsArg.h:499
RooCmdArg Index(RooCategory &icat)
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:35
Bool_t defineSetInternal(const char *name, const RooArgSet &aset)
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements...
static void addClassDeclImportDir(const char *dir)
Add &#39;dir&#39; to search path for class declaration (header) files, when attempting to import class code w...
#define ClassImp(name)
Definition: Rtypes.h:359
RooAbsArg * find(const char *name) const
Find object with given name in list.
std::string _exportNSName
Export contents of workspace to CINT?
Definition: RooWorkspace.h:276
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
Bool_t hasClients() const
Definition: RooAbsArg.h:99
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
RooFIter fwdIterator() const
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
Bool_t removeSet(const char *name)
Remove a named set from the workspace.
Bool_t _doExport
Factory tool associated with workspace.
Definition: RooWorkspace.h:275
unsigned long ULong_t
Definition: RtypesCore.h:51
static Bool_t setAddDirectoryStatus(Bool_t flag)
Definition: RooPlot.cxx:80
virtual void RecursiveRemove(TObject *obj)
If one of the TObject we have a referenced to is deleted, remove the reference.
RooArgSet allResolutionModels() const
Return set with all resolution model objects.
RooRealVar * var(const char *name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found...
const char * GetName() const
Returns name of object.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
#define oocoutW(o, a)
Definition: RooMsgService.h:46
Mother of all ROOT objects.
Definition: TObject.h:37
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:144
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooFactoryWSTool & factory()
Return instance to factory tool.
Bool_t commitTransaction()
Bool_t containsInstance(const RooAbsArg &var) const
std::string listOfClassNames() const
Return STL string with last of class names contained in the code repository.
static void setClassFileExportDir(const char *dir=0)
Specify the name of the directory in which embedded source code is unpacked and compiled.
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
Bool_t import(const RooAbsArg &arg, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg())
Import a RooAbsArg object, e.g.
void clearStudies()
Remove all RooStudyManager modules.
void(* DirAutoAdd_t)(void *, TDirectory *)
Definition: Rtypes.h:110
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
RooExpensiveObjectCache & expensiveObjectCache()
Definition: RooWorkspace.h:155
virtual TObject * Next()=0
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
void setOwning(Bool_t flag)
Definition: RooTObjWrap.h:31
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
void setName(const char *name)
static constexpr double pc
Definition: first.py:1
RooInt is a minimal implementation of a TNamed holding a TObject.
Definition: RooTObjWrap.h:23
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
void setHashTableSize(Int_t i)
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual void ioStreamerPass2()
In which workspace do I live, if any.
Definition: RooAbsArg.cxx:2441
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
void Print(Option_t *opts=0) const
Print contents of the workspace.
RooArgSet allCats() const
Return set with all category objects.
Bool_t redirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t isRecursionStep=kFALSE)
Iterator over _clientListValue.
Definition: RooAbsArg.cxx:925
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1052
Bool_t addStudy(RooAbsStudy &study)
Insert RooStudyManager module.
const Int_t n
Definition: legend1.C:16
static std::string _classFileExportDir
Definition: RooWorkspace.h:252
std::map< std::string, RooArgSet > _namedSets
Definition: RooWorkspace.h:267
char name[80]
Definition: TGX11.cxx:109
RooLinkedList _snapshots
Definition: RooWorkspace.h:264
Bool_t isConstant() const
Definition: RooAbsArg.h:266
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:42
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
RooArgSet allPdfs() const
Return set with all probability density function objects.
RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a functio...
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:27
TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: RooAbsStudy.h:40
void InternalAppend(TObject *obj)
Internal access to TDirectory append method.
Bool_t makeDir()
Create transient TDirectory representation of this workspace.
void exportObj(TObject *obj)
Export reference to given workspace object to CINT.