Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
MakeModelAndMeasurementsFast.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id: cranmer $
2// Author: Kyle Cranmer, Akira Shibata
3/*************************************************************************
4 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
12
13// from roofit
14#include "RooFit/ModelConfig.h"
15
16// from this package
19
20#include "HFMsgService.h"
21
22#include <TFile.h>
23#include <TSystem.h>
24
25#include <string>
26#include <vector>
27#include <map>
28#include <fstream>
29#include <sstream>
30
31/** ********************************************************************************************
32 \ingroup HistFactory
33
34 <p>
35 This is a package that creates a RooFit probability density function from ROOT histograms
36 of expected distributions and histograms that represent the +/- 1 sigma variations
37 from systematic effects. The resulting probability density function can then be used
38 with any of the statistical tools provided within RooStats, such as the profile
39 likelihood ratio, Feldman-Cousins, etc. In this version, the model is directly
40 fed to a likelihood ratio test, but it needs to be further factorized.</p>
41
42 <p>
43 The user needs to provide histograms (in picobarns per bin) and configure the job
44 with XML. The configuration XML is defined in the file `$ROOTSYS/config/HistFactorySchema.dtd`, but essentially
45 it is organized as follows (see the examples in `${ROOTSYS}/tutorials/roofit/histfactory/`)</p>
46
47 <ul>
48 <li> a top level 'Combination' that is composed of:</li>
49 <ul>
50 <li> several 'Channels' (eg. ee, emu, mumu), which are composed of:</li>
51 <ul>
52 <li> several 'Samples' (eg. signal, bkg1, bkg2, ...), each of which has:</li>
53 <ul>
54 <li> a name</li>
55 <li> if the sample is normalized by theory (eg N = L*sigma) or not (eg. data driven)</li>
56 <li> a nominal expectation histogram</li>
57 <li> a named 'Normalization Factor' (which can be fixed or allowed to float in a fit)</li>
58 <li> several 'Overall Systematics' in normalization with:</li>
59 <ul>
60 <li> a name</li>
61 <li> +/- 1 sigma variations (eg. 1.05 and 0.95 for a 5% uncertainty)</li>
62 </ul>
63 <li> several 'Histogram Systematics' in shape with:</li>
64 <ul>
65 <li> a name (which can be shared with the OverallSyst if correlated)</li>
66 <li> +/- 1 sigma variational histograms</li>
67 </ul>
68 </ul>
69 </ul>
70 <li> several 'Measurements' (corresponding to a full fit of the model) each of which specifies</li>
71 <ul>
72 <li> a name for this fit to be used in tables and files</li>
73 <li> what is the luminosity associated to the measurement in picobarns</li>
74 <li> which bins of the histogram should be used</li>
75 <li> what is the relative uncertainty on the luminosity </li>
76 <li> what is (are) the parameter(s) of interest that will be measured</li>
77 <li> which parameters should be fixed/floating (eg. nuisance parameters)</li>
78 </ul>
79 </ul>
80 </ul>
81*/
84 HistoToWorkspaceFactoryFast::Configuration const &cfg)
85{
86 std::unique_ptr<TFile> outFile;
87
89 msgSvc.getStream(1).removeTopic(RooFit::ObjectHandling);
90
91 cxcoutIHF << "Making Model and Measurements (Fast) for measurement: " << measurement.GetName() << std::endl;
92
93 double lumiError = measurement.GetLumi()*measurement.GetLumiRelErr();
94
95 cxcoutIHF << "using lumi = " << measurement.GetLumi() << " and lumiError = " << lumiError
96 << " including bins between " << measurement.GetBinLow() << " and " << measurement.GetBinHigh() << std::endl;
97
98 std::ostringstream parameterMessage;
99 parameterMessage << "fixing the following parameters:" << std::endl;
100
101 for (auto const &name : measurement.GetConstantParams()) {
102 parameterMessage << " " << name << '\n';
103 }
105
106 std::string rowTitle = measurement.GetName();
107
108 std::vector<std::unique_ptr<RooWorkspace>> channel_workspaces;
109 std::vector<std::string> channel_names;
110
111 // Create the outFile - first check if the outputfile exists
112 std::string prefix = measurement.GetOutputFilePrefix();
113 // parse prefix to find output directory -
114 // assume there is a file prefix after the last "/" that we remove
115 // to get the directory name.
116 // We do by finding last occurrence of "/" and using as directory name what is before
117 // if we do not have a "/" in the prefix there is no output directory to be checked or created
118 size_t pos = prefix.rfind('/');
119 if (pos != std::string::npos) {
120 std::string outputDir = prefix.substr(0,pos);
121 cxcoutDHF << "Checking if output directory : " << outputDir << " - exists" << std::endl;
122 void *outdir = gSystem->OpenDirectory( outputDir.c_str() );
123 if (outdir == nullptr) {
124 cxcoutDHF << "Output directory : " << outputDir << " - does not exist, try to create" << std::endl;
125 int success = gSystem->MakeDirectory( outputDir.c_str() );
126 if( success != 0 ) {
127 std::string fullOutputDir = std::string(gSystem->pwd()) + std::string("/") + outputDir;
128 cxcoutEHF << "Error: Failed to make output directory: " << fullOutputDir << std::endl;
129 throw hf_exc();
130 }
131 } else {
133 }
134 }
135
136 // This holds the TGraphs that are created during the fit
137 std::string outputFileName = measurement.GetOutputFilePrefix() + "_" + measurement.GetName() + ".root";
138 cxcoutIHF << "Creating the output file: " << outputFileName << std::endl;
139 outFile = std::make_unique<TFile>(outputFileName.c_str(), "recreate");
140
141 cxcoutIHF << "Creating the HistoToWorkspaceFactoryFast factory" << std::endl;
142 HistoToWorkspaceFactoryFast factory{measurement, cfg};
143
144 // Make the factory, and do some preprocessing
145 // HistoToWorkspaceFactoryFast factory(measurement, rowTitle, outFile);
146 cxcoutIHF << "Setting preprocess functions" << std::endl;
147 factory.SetFunctionsToPreprocess( measurement.GetPreprocessFunctions() );
148
149 // First: Loop to make the individual channels
150 for( unsigned int chanItr = 0; chanItr < measurement.GetChannels().size(); ++chanItr ) {
151
152 HistFactory::Channel& channel = measurement.GetChannels().at( chanItr );
153 if( ! channel.CheckHistograms() ) {
154 cxcoutEHF << "MakeModelAndMeasurementsFast: Channel: " << channel.GetName()
155 << " has uninitialized histogram pointers" << std::endl;
156 throw hf_exc();
157 }
158
159 // Make the workspace for this individual channel
160 std::string ch_name = channel.GetName();
161 cxcoutPHF << "Starting to process channel: " << ch_name << std::endl;
162 channel_names.push_back(ch_name);
163 std::unique_ptr<RooWorkspace> ws_single{factory.MakeSingleChannelModel( measurement, channel )};
164
165 if (cfg.createPerRegionWorkspaces) {
166 // Make the output
167 std::string ChannelFileName = measurement.GetOutputFilePrefix() + "_"
168 + ch_name + "_" + rowTitle + "_model.root";
169 cxcoutIHF << "Opening File to hold channel: " << ChannelFileName << std::endl;
170 std::unique_ptr<TFile> chanFile{TFile::Open( ChannelFileName.c_str(), "RECREATE" )};
171 chanFile->WriteTObject(ws_single.get());
172 // Now, write the measurement to the file
173 // Make a new measurement for only this channel
175 meas_chan.GetChannels().clear();
176 meas_chan.GetChannels().push_back( channel );
177 cxcoutIHF << "About to write channel measurement to file" << std::endl;
178 meas_chan.writeToFile( chanFile.get() );
179 cxcoutPHF << "Successfully wrote channel to file" << std::endl;
180 }
181
182 channel_workspaces.emplace_back(std::move(ws_single));
183 } // End loop over channels
184
185 /***
186 Second: Make the combined model:
187 If you want output histograms in root format, create and pass it to the combine routine.
188 "combine" : will do the individual cross-section measurements plus combination
189 ***/
190
191 // Use HistFactory to combine the individual channel workspaces
192 std::unique_ptr<RooWorkspace> ws{factory.MakeCombinedModel(channel_names, channel_workspaces)};
193
194 // Configure that workspace
195 HistoToWorkspaceFactoryFast::ConfigureWorkspaceForMeasurement("simPdf", ws.get(), measurement);
196
197 {
198 std::string CombinedFileName = measurement.GetOutputFilePrefix() + "_combined_"
199 + rowTitle + "_model.root";
200 cxcoutPHF << "Writing combined workspace to file: " << CombinedFileName << std::endl;
201 std::unique_ptr<TFile> combFile{TFile::Open( CombinedFileName.c_str(), "RECREATE" )};
202 if( combFile == nullptr ) {
203 cxcoutEHF << "Error: Failed to open file " << CombinedFileName << std::endl;
204 throw hf_exc();
205 }
206 combFile->WriteTObject(ws.get());
207 cxcoutPHF << "Writing combined measurement to file: " << CombinedFileName << std::endl;
208 measurement.writeToFile( combFile.get() );
209 }
210
211 msgSvc.getStream(1).addTopic(RooFit::ObjectHandling);
212
213 return RooFit::makeOwningPtr(std::move(ws));
214}
#define cxcoutPHF
#define cxcoutDHF
#define cxcoutIHF
#define cxcoutEHF
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.
char name[80]
Definition TGX11.cxx:110
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
static RooMsgService & instance()
Return reference to singleton instance.
The RooStats::HistFactory::Measurement class can be used to construct a model by combining multiple R...
Definition Measurement.h:31
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:4131
const char * pwd()
Definition TSystem.h:434
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:857
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:848
virtual int MakeDirectory(const char *name)
Make a directory.
Definition TSystem.cxx:838
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
@ ObjectHandling
OwningPtr< T > makeOwningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
Definition Config.h:40
RooFit::OwningPtr< RooWorkspace > MakeModelAndMeasurementFast(RooStats::HistFactory::Measurement &measurement, HistoToWorkspaceFactoryFast::Configuration const &cfg={})