Please help me diagnose the problem I have fetching a ModelConfig stored inside a RooWorkspace in a file.
The attached macro createThings.C can be run in different modes to perform the following simple steps:
create a RooWorkspace containing a single RooRealVar
create a RooAddPdf inside the workspace
create a ModelConfig referencing stuff in the workspace and import
Each step is accomplished by opening the workspace file, grabbing the workspace, making the thing, and then overwriting the workspace file with the new workspace. Therefore, I would expect the following two modes to be equivalent:
(1) INSIDE MACRO Do all three creation steps in one ROOT command:
root createThings.C\(\"workspace,pdf,model\"\)
(1) Printout:
=== Using the following for model ===
Observables: RooArgSet:: = (x)
PDF: RooAddPdf::bkgPlusSigModel[ bkgSize * bkgModel + sigSize * sigModel ] = 0.0501007
(2) OUTSIDE MACRO: Do each creation step in three separate ROOT commands:
=== Using the following for model ===
[#0] ERROR:ObjectHandling -- workspace not set
As you can see, the printout of mode (2) indicates that the ModelConfig has lost contact with its workspace (ironically the very workspace in which it lives). Unfortunately the workspace not set error renders the ModelConfig unusable. This is problematic since it is often desirable to do model building in separate command stages (mode 2) instead of doing all steps inside a single macro (mode 1).
Any help understanding this behaviour is greatly appreciated!
Etienne
Clue:
Modes (1) and (2) above produce equivalent output when the RooAddPdf creation step is skipped, so that the ModelConfig only references the single RooRealVar x in the workspace and no pdf:
the only thing I can say for now is that a TRef is at fault, an evil zombie from earlier times.
I don’t know what it gets wrong, but it’s about object numbers in processes. If you end the process in between work items, and a ModelConfig is created, the unique IDs of objects start at 0 or 1 again. Now, the TRef might point not to a workspace, but to a <insert class here> …
When it fails, we are at:
(lldb) print fRefWS.GetObject()
(RooListProxy *) $0 = 0x0000000112ddceb8 <--- This should have been the workspace ...
(lldb) print *fRefWS.GetObject()
(TObject) $1 = (fUniqueID = 1, fBits = 50331672)
@pcanal, any idea?
Don’t use TRef or don’t end the process, I assume?
Hello @StephanH, thank you for this helpful insight!
I see… since you pointed me in this direction of the TRef I tried printing out the TProcessID::GetObjectCount() before and after each creation step and found the following:
After creating RooWorkspace with single RooRealVar: 0
After creating RooAddPdf via factory call: 12
Before creating the ModelConfig: 0
After creating the Model Config: 1
in mode 2 (three successive ROOT sessions). Apparently the object count gets reset after writing the workspace containing the newly-created RooAddPdf and opening it again to create the ModelConfig (why??). This causes the workspace TRef to be misplaced I guess. However when running all three steps in the same ROOT session (mode 1) the object count does not get reset to 0 and there is no problem.
I was able to hack my macro ==> createThings_fix.C so that after each creation step the object count is recorded in a dedicated RooRealVar objectCount in the workspace before writing. Likewise before each creation step the object count is updated via TProcessID::SetObjectCount() using the stored value in the objectCount RooRealVar. This “by hand” solution is quite cumbersome, but it fixes the problem… please share if you have a better workaround!!
No, not really. TRef shouldn’t have been used in the first place, but it’s not so easy to change, because it will break everything that’s currently on disc.