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