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