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