43 plotHypoTestResult =
True
50 generateBinned =
False
55 enableDetailedOutput = (
61 rebuildParamValues = 0
86large_declaration =
""" \
89class HypoTestInvTool {
95 HypoTestInverterResult *RunInverter(RooWorkspace *w, const char *modelSBName, const char *modelBName,
96 const char *dataName, int type, int testStatType, bool useCLs, int npoints,
97 double poimin, double poimax, int ntoys, bool useNumberCounting = false,
98 const char *nuisPriorName = 0);
100 void AnalyzeResult(HypoTestInverterResult *r, int calculatorType, int testStatType, bool useCLs, int npoints,
101 const char *fileNameBase = 0);
103 void SetParameter(const char *name, const char *value);
104 void SetParameter(const char *name, bool value);
105 void SetParameter(const char *name, int value);
106 void SetParameter(const char *name, double value);
110 bool mPlotHypoTestResult;
113 bool mUseVectorStore;
114 bool mGenerateBinned;
117 bool mEnableDetOutput;
119 int mRebuildParamValues;
126 std::string mMassValue;
128 mMinimizerType; // minimizer type (default is what is in ROOT::Math::MinimizerOptions::DefaultMinimizerType())
129 TString mResultFileName;
132} // end using RooStats namespace
134RooStats::HypoTestInvTool::HypoTestInvTool()
135 : mPlotHypoTestResult(true), mWriteResult(false), mOptimize(true), mUseVectorStore(true), mGenerateBinned(false),
136 mEnableDetOutput(false), mRebuild(false), mReuseAltToys(false),
137 mNToyToRebuild(100), mRebuildParamValues(0), mPrintLevel(0), mInitialFit(-1), mRandomSeed(-1), mNToysRatio(2),
138 mMaxPoi(-1), mAsimovBins(0), mMassValue(""), mMinimizerType(""), mResultFileName()
149 def SetParameter(self, name, value):
150 if (
type(name)
is str)
and (
type(value)
is str):
158 self.mPlotHypoTestResult = value
160 self.mWriteResult = value
162 self.mOptimize = value
164 self.mUseVectorStore = value
166 self.mGenerateBinned = value
168 self.mEnableDetOutput = value
170 self.mRebuild = value
172 self.mReuseAltToys = value
179 elif (
type(name)
is str)
and (
type(value)
is bool):
188 self.mNToyToRebuild = value
190 self.mRebuildParamValues = value
192 self.mPrintLevel = value
194 self.mInitialFit = value
196 self.mRandomSeed = value
198 self.mAsimovBins = value
205 elif (
type(name)
is str)
and (
type(value)
is int):
214 self.mNToysRatio = value
223 elif (
type(name)
is str)
and (
type(value)
is (float
or double)):
232 global gselfmMassValue
233 gselfmMassValue = self.mMassValue
234 self.mMassValue = value
236 self.mMassValue = value
238 self.mResultFileName = value
248 def AnalyzeResult(self, r, calculatorType, testStatType, useCLs, npoints, fileNameBase):
270 if lowerLimit < upperLimit * (1.0 - 1.0e-4)
and lowerLimit != 0:
271 print(f
"The computed lower limit is: ", lowerLimit,
" +/- ", llError)
273 print(f
"The computed upper limit is: {upperLimit} +/- ", ulError)
276 print(f
"Expected upper limits, using the B (alternate) model : ")
284 if self.mEnableDetOutput:
285 self.mWriteResult =
True
286 ROOT.Info(
"StandardHypoTestInvDemo",
"detailed output will be written in output result file")
292 calcType =
"Freq" if (calculatorType == 0)
else (
"Hybr" if (calculatorType == 1)
else "Asym")
293 limitType =
"CLs" if (useCLs)
else "Cls+b"
294 scanType =
"auto" if (npoints < 0)
else "grid"
295 if self.mResultFileName.IsNull():
297 "%s_%s_%s_ts%d_", calcType, limitType, scanType, testStatType
300 if self.mMassValue.
size() > 0:
301 self.mResultFileName += self.mMassValue
302 self.mResultFileName +=
"_"
306 self.mResultFileName += name
309 uldistFile =
"RULDist.root"
317 fileOut =
TFile(self.mResultFileName,
"RECREATE")
322 "StandardHypoTestInvDemo",
323 "HypoTestInverterResult has been written in the file %s",
324 self.mResultFileName.Data(),
331 if calculatorType == 0:
332 typeName =
"Frequentist"
333 if calculatorType == 1:
335 elif calculatorType == 2
or calculatorType == 3:
336 typeName =
"Asymptotic"
337 self.mPlotHypoTestResult =
False
340 plotTitle =
"{} CL Scan for workspace {}".
format(str(typeName), resultName)
346 c1Name =
"{}_Scan".
format(typeName)
357 c1.SaveAs(
"StandardHypoTestInvDemo.c1.png")
362 if self.mPlotHypoTestResult:
369 for i
in range(nEntries):
377 c2.SaveAs(
"StandardHypoTestInvDemo.c2.png")
402 print(f
"Running HypoTestInverter on the workspace ",
w.GetName())
408 Error(
"StandardHypoTestDemo",
"Not existing data {}".
format(dataName))
411 print(f
"Using data set ", dataName)
413 if self.mUseVectorStore:
419 bModel =
w.obj(modelBName)
420 sbModel =
w.obj(modelSBName)
423 Error(
"StandardHypoTestDemo",
"Not existing ModelConfig %s", modelSBName)
428 Error(
"StandardHypoTestDemo",
"Model %s has no pdf ", modelSBName)
432 Error(
"StandardHypoTestDemo",
"Model %s has no poi ", modelSBName)
436 Error(
"StandardHypoTestInvDemo",
"Model %s has no observables ", modelSBName)
441 "StandardHypoTestInvDemo",
"Model {} has no snapshot - make one using model poi".
format(modelSBName)
451 f
"StandardHypoTestInvDemo",
452 " - Switch off all systematics by setting them constant to their initial values",
461 if (
not bModel)
or (bModel == sbModel):
462 ROOT.Info(
"StandardHypoTestInvDemo",
"The background model {} does not exist".
format(modelBName))
463 ROOT.Info(
"StandardHypoTestInvDemo",
"Copy it from ModelConfig {} and set POI to zero".
format(modelSBName))
476 "StandardHypoTestInvDemo",
477 "Model %s has no snapshot - make one using model poi and 0 values ",
487 Error(
"StandardHypoTestInvDemo",
"Model %s has no valid poi", modelBName)
495 if hasNuisParam
and not hasGlobalObs:
500 "StandardHypoTestInvDemo",
501 "Model %s has nuisance parameters but no global observables associated",
505 "StandardHypoTestInvDemo",
506 "\tThe effect of the nuisance parameters will not be treated correctly ",
524 doFit = self.mInitialFit
525 if testStatType == 0
and self.mInitialFit == -1:
527 if type == 3
and self.mInitialFit == -1:
531 if len(self.mMinimizerType) == 0:
537 "StandardHypoTestInvDemo",
538 "Using {} as minimizer for computing the test statistic".
format(
549 ROOT.Info(
"StandardHypoTestInvDemo",
" Doing a first fit to the observed data ")
559 Minimizer(str(self.mMinimizerType),
"Migrad"),
561 PrintLevel(self.mPrintLevel),
562 Constrain(constrainParams),
569 "StandardHypoTestInvDemo",
570 "Fit to the model failed - try with strategy 1 and perform first an Hesse computation",
576 Minimizer(self.mMinimizerType,
"Migrad"),
578 PrintLevel(self.mPrintLevel + 1),
579 Constrain(constrainParams),
585 Warning(
"StandardHypoTestInvDemo",
" Fit still failed - continue anyway.....")
588 print(f
"Time for fitting : ")
593 print(f
"StandardHypoTestInvo: snapshot of S+B Model ",
sbModel.GetName(),
" is set to the best fit value")
596 if testStatType == 0:
599 "StandardHypoTestInvDemo",
600 "Using LEP test statistic - an initial fit is not done and the TS will use "
601 +
"the nuisances at the model value",
605 "StandardHypoTestInvDemo",
606 "Using LEP test statistic - an initial fit has been done and the TS will use "
607 +
"the nuisances at the best fit value",
625 if self.mEnableDetOutput:
631 if testStatType == 11:
635 if self.mEnableDetOutput:
639 if testStatType == 3:
641 if testStatType == 4:
645 if self.mEnableDetOutput:
680 data, bModel, sbModel,
True
684 "StandardHypoTestInvDemo",
685 "Invalid - calculator type = {Type}supported values are only :\n\t\t\t 0 "
686 +
"(Frequentist) , 1 (Hybrid) , 2 (Asymptotic) ",
693 if testStatType == 0:
695 if testStatType == 1
or testStatType == 11:
697 if testStatType == 2
or testStatType == 3
or testStatType == 4:
699 if testStatType == 5:
701 if testStatType == 6:
706 "StandardHypoTestInvDemo",
707 "Invalid - test statistic type = {testStatType} supported values are only :\n\t\t\t 0 (SLR) "
708 +
", 1 (Tevatron) , 2 (PLR), 3 (PLR1), 4(MLE)",
714 if toymcs
and (Type == 0
or Type == 1):
717 if useNumberCounting:
718 Warning(
"StandardHypoTestInvDemo",
"Pdf is extended: but number counting flag is set: ignore it ")
721 if not useNumberCounting:
724 "StandardHypoTestInvDemo",
725 "Pdf is not extended: number of events to generate taken from observed data set is {nEvents}",
729 ROOT.Info(
"StandardHypoTestInvDemo",
"using a number counting pdf")
736 "StandardHypoTestInvDemo",
738 "Data set is weighted, nentries = {} and sum of weights = {:8.1f} but toy"
739 +
"generation is unbinned - it would be faster to set self.mGenerateBinned to true\n"
749 "StandardHypoTestInvDemo",
751 "generate binned is activated but the number of observable is {}. Too much "
752 +
"memory could be needed for allocating all the bins"
757 if self.mRandomSeed >= 0:
761 if self.mReuseAltToys:
765 hhc = HybridCalculator(hc)
783 nuisPdf =
w.pdf(nuisPriorName)
787 "StandardHypoTestInvDemo",
788 "No nuisance pdf given for the HybridCalculator - try to deduce pdf from the model",
799 "StandardHypoTestInvDemo",
800 "No nuisance pdf given - try to use %s that is defined as a prior pdf in the B model",
805 "StandardHypoTestInvDemo",
806 "Cannot run Hybrid calculator because no prior on the nuisance "
807 "parameter is specified or can be derived",
812 ROOT.Info(
"StandardHypoTestInvDemo",
"Using as nuisance Pdf ... ")
823 "StandardHypoTestInvDemo",
824 "Prior nuisance does not depend on nuisance parameters. They will be smeared in their full range",
830 elif type == 2
or type == 3:
831 if testStatType == 3:
833 if testStatType != 2
and testStatType != 3:
835 "StandardHypoTestInvDemo",
836 "Only the PL test statistic can be used with AsymptoticCalculator - use by default a two-sided PL",
841 if self.mEnableDetOutput:
864 print(f
"Doing a fixed scan in interval : {poimin}, {poimax} ")
868 print(f
"Doing an automatic scan in interval : {poi.getMin()} , ",
poi.getMax())
872 print(f
"Time to perform limit scan \n")
879 f
"Rebuild the upper limit distribution by re-generating new set of pseudo-experiment and re-compute "
880 +
"for each of them a new upper limit\n\n"
888 if self.mRebuildParamValues != 0:
892 if self.mRebuildParamValues == 0
or self.mRebuildParamValues == 1:
902 if self.mRebuildParamValues == 0:
910 Minimizer(self.mMinimizerType,
"Migrad"),
912 PrintLevel(self.mPrintLevel),
913 Constrain(constrainParams),
917 print(f
"rebuild using fitted parameter value for B-model snapshot")
922 print(f
"StandardHypoTestInvDemo: Initial parameters used for rebuilding: ")
927 print(f
"Time to rebuild distributions :")
931 print(f
"Expected limits after rebuild distribution ")
932 print(f
"expected upper limit (median of limit distribution) ",
limDist.InverseCDF(0.5))
934 f
"expected -1 sig limit (0.16% quantile of limit dist) ",
938 f
"expected +1 sig limit (0.84% quantile of limit dist) ",
942 f
"expected -2 sig limit (.025% quantile of limit dist) ",
946 f
"expected +2 sig limit (.975% quantile of limit dist) ",
951 limPlot = SamplingDistPlot(50
if (self.mNToyToRebuild < 200)
else 100)
955 c1 =
TCanvas(
"limPlot",
"Upper Limit Distribution")
959 c1.SaveAs(
"StandardHypoTestInvDemo.1.png")
963 fileOut =
TFile(
"RULDist.root",
"RECREATE")
974 print(f
"ERROR : failed to re-build distributions ")
988def StandardHypoTestInvDemo(
991 modelSBName="ModelConfig",
1001 useNumberCounting=False,
1006 Other Parameter to pass in tutorial
1007 apart from standard for filename, ws, modelconfig and data
1009 type = 0 Freq calculator
1010 type = 1 Hybrid calculator
1011 type = 2 Asymptotic calculator
1012 type = 3 Asymptotic calculator using nominal Asimov data sets (not using fitted parameter values but nominal ones)
1014 testStatType = 0 LEP
1022 useCLs scan for CLs (otherwise for CLs+b)
1026 poimin,poimax: min/max value to scan in case of fixed scans
1027 (if min > max, try to find automatically)
1029 ntoys: number of toys to use
1031 useNumberCounting: set to True when using number counting events
1033 nuisPriorName: name of prior for the nuisance. This is often expressed as constraint term in the global model
1034 HybridCalculator (type=1)
1035 If not given by default the prior pdf from ModelConfig is used.
1037 extra options are available as global parameters of the macro. They major ones are:
1039 plotHypoTestResult plot result of tests at each point (TS distributions) (default is True)
1040 writeResult write result of scan (default is True)
1041 rebuild rebuild scan for expected limits (require extra toys) (default is False)
1042 generateBinned generate binned data sets for toys (default is False) - be careful not to activate with
1043 large (>=3) number of observables
1044 nToyRatio ratio of S+B/B toys (default is 2)
1049 filename =
"results/example_combined_GaussExample_model.root"
1054 print(
"HistFactory file cannto be generated on Windows - exit")
1057 print(f
"will run standard hist2workspace example")
1060 print(f
"\n\n---------------------")
1061 print(f
"Done creating example input")
1062 print(f
"---------------------\n\n")
1072 print(f
"StandardRooStatsDemoMacro: Input file {filename} is not found")
1105 print(w,
"\t", filename)
1123 raise RuntimeError(
"Error running the HypoTestInverter - Exit ")
1128 print(f
"Reading an HypoTestInverterResult with name {wsName} from file " << filename)
1131 raise RuntimeError(
"File {filename} does not contain a workspace or an HypoTestInverterResult - Exit ")
1144def ReadResult(fileName, resultName="", useCLs=True):
1146 StandardHypoTestInvDemo(fileName, resultName,
"",
"",
"", 0, 0, useCLs)
1151 StandardHypoTestInvDemo()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
RooArgSet is a container object that can hold multiple RooAbsArg objects.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...