Logo ROOT   6.18/05
Reference Guide
ProofSimpleFile.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_ProofSimpleFile
3///
4/// Selector to fill a set of histograms and merging via file
5///
6/// \macro_code
7///
8/// \author Gerardo Ganis (gerardo.ganis@cern.ch)
9
10#define ProofSimpleFile_cxx
11
12#include "ProofSimpleFile.h"
13#include <TCanvas.h>
14#include <TFrame.h>
15#include <TPaveText.h>
16#include <TFormula.h>
17#include <TF1.h>
18#include <TH1F.h>
19#include <TMath.h>
20#include <TRandom3.h>
21#include <TString.h>
22#include <TStyle.h>
23#include <TSystem.h>
24#include <TParameter.h>
25#include <TFile.h>
26#include <TProofOutputFile.h>
27
28//_____________________________________________________________________________
29ProofSimpleFile::ProofSimpleFile()
30{
31 // Constructor
32
33 fNhist = 16;
34 fHistTop = 0;
35 fHistDir = 0;
36 fRandom = 0;
37 fFile = 0;
38 fProofFile = 0;
39 fFileDir = 0;
40}
41
42//_____________________________________________________________________________
43ProofSimpleFile::~ProofSimpleFile()
44{
45 // Destructor
46
47 if (fRandom) delete fRandom;
48}
49
50//_____________________________________________________________________________
51Int_t ProofSimpleFile::CreateHistoArrays()
52{
53 // Create the histogram arrays
54
55 if (fNhist <= 0) {
56 Error("CreateHistoArrays", "fNhist must be positive!");
57 return -1;
58 }
59 // Histos array
60 fHistTop = new TH1F*[fNhist];
61 fHistDir = new TH1F*[fNhist];
62 // Done
63 return 0;
64}
65
66//_____________________________________________________________________________
67void ProofSimpleFile::Begin(TTree * /*tree*/)
68{
69 // The Begin() function is called at the start of the query.
70 // When running with PROOF Begin() is only called on the client.
71 // The tree argument is deprecated (on PROOF 0 is passed).
72
73 TString option = GetOption();
74
75 // Number of histograms (needed in terminate)
76 Ssiz_t iopt = kNPOS;
77 if (fInput->FindObject("ProofSimpleFile_NHist")) {
79 dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimpleFile_NHist"));
80 fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
81 } else if ((iopt = option.Index("nhist=")) != kNPOS) {
82 TString s;
83 Ssiz_t from = iopt + strlen("nhist=");
84 if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
85 }
86}
87
88//_____________________________________________________________________________
89void ProofSimpleFile::SlaveBegin(TTree * /*tree*/)
90{
91 // The SlaveBegin() function is called after the Begin() function.
92 // When running with PROOF SlaveBegin() is called on each slave server.
93 // The tree argument is deprecated (on PROOF 0 is passed).
94
95 TString option = GetOption();
96
97 // Number of histograms (needed in terminate)
98 Ssiz_t iopt = kNPOS;
99 if (fInput->FindObject("ProofSimpleFile_NHist")) {
101 dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimpleFile_NHist"));
102 fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
103 } else if ((iopt = option.Index("nhist=")) != kNPOS) {
104 TString s;
105 Ssiz_t from = iopt + strlen("nhist=");
106 if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
107 }
108
109 // The file for merging
110 fProofFile = new TProofOutputFile("SimpleFile.root", "M");
111 TNamed *out = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE");
112 if (out) fProofFile->SetOutputFileName(out->GetTitle());
113 TDirectory *savedir = gDirectory;
114 fFile = fProofFile->OpenFile("RECREATE");
115 if (fFile && fFile->IsZombie()) SafeDelete(fFile);
116 savedir->cd();
117
118 // Cannot continue
119 if (!fFile) {
120 TString amsg = TString::Format("ProofSimpleFile::SlaveBegin: could not create '%s':"
121 " instance is invalid!", fProofFile->GetName());
122 Abort(amsg, kAbortProcess);
123 return;
124 }
125
126 // Histos arrays
127 if (CreateHistoArrays() != 0) {
128 Abort("ProofSimpleFile::SlaveBegin: could not create histograms", kAbortProcess);
129 return;
130 }
131
132 // Create directory
133 if (!(fFileDir = fFile->mkdir("blue"))) {
134 Abort("ProofSimpleFile::SlaveBegin: could not create directory 'blue' in file!",
135 kAbortProcess);
136 return;
137 }
138
139 // Create the histograms
140 for (Int_t i=0; i < fNhist; i++) {
141 fHistTop[i] = new TH1F(Form("ht%d",i), Form("ht%d",i), 100, -3., 3.);
142 fHistTop[i]->SetFillColor(kRed);
143 fHistTop[i]->SetDirectory(fFile);
144 fHistDir[i] = new TH1F(Form("hd%d",i), Form("hd%d",i), 100, -3., 3.);
145 fHistDir[i]->SetFillColor(kBlue);
146 fHistDir[i]->SetDirectory(fFileDir);
147 }
148
149 // Set random seed
150 fRandom = new TRandom3(0);
151}
152
153//_____________________________________________________________________________
154Bool_t ProofSimpleFile::Process(Long64_t)
155{
156 // The Process() function is called for each entry in the tree (or possibly
157 // keyed object in the case of PROOF) to be processed. The entry argument
158 // specifies which entry in the currently loaded tree is to be processed.
159 // It can be passed to either ProofSimpleFile::GetEntry() or TBranch::GetEntry()
160 // to read either all or the required parts of the data. When processing
161 // keyed objects with PROOF, the object is already loaded and is available
162 // via the fObject pointer.
163 //
164 // This function should contain the "body" of the analysis. It can contain
165 // simple or elaborate selection criteria, run algorithms on the data
166 // of the event and typically fill histograms.
167 //
168 // The processing can be stopped by calling Abort().
169 //
170 // Use fStatus to set the return value of TTree::Process().
171 //
172 // The return value is currently not used.
173
174 for (Int_t i=0; i < fNhist; i++) {
175 if (fRandom && fHistTop[i] && fHistDir[i]) {
176 fHistTop[i]->Fill(fRandom->Gaus(0.,1.));
177 fHistDir[i]->Fill(fRandom->Gaus(0.,1.));
178 }
179 }
180
181 return kTRUE;
182}
183
184//_____________________________________________________________________________
185void ProofSimpleFile::SlaveTerminate()
186{
187 // The SlaveTerminate() function is called after all entries or objects
188 // have been processed. When running with PROOF SlaveTerminate() is called
189 // on each slave server.
190
191 // Write histos to file
192 if (fFile) {
193 Bool_t cleanup = kTRUE;
194 TDirectory *savedir = gDirectory;
195 fFile->cd();
196 for (Int_t i=0; i < fNhist; i++) {
197 if (fHistTop[i] && fHistTop[i]->GetEntries() > 0) {
198 fHistTop[i]->Write();
199 fHistTop[i]->SetDirectory(0);
200 cleanup = kFALSE;
201 }
202 }
203 // Change to subdirectory
204 fFileDir->cd();
205 for (Int_t i=0; i < fNhist; i++) {
206 if (fHistDir[i] && fHistDir[i]->GetEntries() > 0) {
207 fHistDir[i]->Write();
208 fHistDir[i]->SetDirectory(0);
209 cleanup = kFALSE;
210 }
211 }
212 gDirectory = savedir;
213 fFile->Close();
214 // Cleanup or register
215 if (cleanup) {
216 Info("SlaveTerminate", "nothing to save: just cleanup everything ...");
217 TUrl uf(*(fFile->GetEndpointUrl()));
218 SafeDelete(fFile);
219 gSystem->Unlink(uf.GetFile());
220 SafeDelete(fProofFile);
221 } else {
222 Info("SlaveTerminate", "objects saved into '%s%s': sending related TProofOutputFile ...",
223 fProofFile->GetFileName(), fProofFile->GetOptionsAnchor());
224 fProofFile->Print();
225 fOutput->Add(fProofFile);
226 }
227 }
228
229}
230
231//_____________________________________________________________________________
232void ProofSimpleFile::Terminate()
233{
234 // The Terminate() function is the last function to be called during
235 // a query. It always runs on the client, it can be used to present
236 // the results graphically or save the results to file.
237
238 // Get the histos from the file
239 if ((fProofFile =
240 dynamic_cast<TProofOutputFile*>(fOutput->FindObject("SimpleFile.root")))) {
241
242 TString outputFile(fProofFile->GetOutputFileName());
243 TString outputName(fProofFile->GetName());
244 outputName += ".root";
245 Printf("outputFile: %s", outputFile.Data());
246
247 // Read the ntuple from the file
248 if (!(fFile = TFile::Open(outputFile))) {
249 Error("Terminate", "could not open file: %s", outputFile.Data());
250 return;
251 }
252
253 } else {
254 Error("Terminate", "TProofOutputFile not found");
255 return;
256 }
257
258 // Histos arrays
259 if (CreateHistoArrays() != 0) {
260 Error("Terminate", "could not create histograms");
261 return;
262 }
263
264 // Top histos
265 PlotHistos(0);
266 // Dir histos
267 PlotHistos(1);
268}
269
270//_____________________________________________________________________________
271void ProofSimpleFile::PlotHistos(Int_t opt)
272{
273 // Plot the histograms ina dedicated canvas
274
275 // Create a canvas, with fNhist pads
276 if (opt == 0) {
277 TCanvas *c1 = new TCanvas("c1","ProofSimpleFile top dir canvas",200,10,700,700);
278 Int_t nside = (Int_t)TMath::Sqrt((Float_t)fNhist);
279 nside = (nside*nside < fNhist) ? nside+1 : nside;
280 c1->Divide(nside,nside,0,0);
281
282 for (Int_t i=0; i < fNhist; i++) {
283 fHistTop[i] = (TH1F *) fFile->Get(TString::Format("ht%d",i));
284 c1->cd(i+1);
285 if (fHistTop[i])
286 fHistTop[i]->Draw();
287 }
288
289 // Final update
290 c1->cd();
291 c1->Update();
292 } else if (opt == 1) {
293 TCanvas *c2 = new TCanvas("c2","ProofSimpleFile 'blue' sub-dir canvas",400,60,700,700);
294 Int_t nside = (Int_t)TMath::Sqrt((Float_t)fNhist);
295 nside = (nside*nside < fNhist) ? nside+1 : nside;
296 c2->Divide(nside,nside,0,0);
297
298 if ((fFileDir = (TDirectory *) fFile->Get("blue"))) {
299 for (Int_t i=0; i < fNhist; i++) {
300 fHistDir[i] = (TH1F *) fFileDir->Get(TString::Format("hd%d",i));
301 c2->cd(i+1);
302 if (fHistDir[i])
303 fHistDir[i]->Draw();
304 }
305 } else {
306 Error("PlotHistos", "directory 'blue' not found in output file");
307 }
308
309 // Final update
310 c2->cd();
311 c2->Update();
312 } else {
313 Error("PlotHistos", "unknown option: %d", opt);
314 }
315}
Selector to fill a set of histograms and merging via file.
#define SafeDelete(p)
Definition: RConfig.hxx:543
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
long long Long64_t
Definition: RtypesCore.h:69
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
@ kRed
Definition: Rtypes.h:64
@ kBlue
Definition: Rtypes.h:64
#define gDirectory
Definition: TDirectory.h:218
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
The Canvas class.
Definition: TCanvas.h:31
Describe directory structure in memory.
Definition: TDirectory.h:34
virtual void Close(Option_t *option="")
Delete all objects from memory and directory structure itself.
Definition: TDirectory.cxx:584
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Definition: TDirectory.cxx:497
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3980
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:321
Named parameter, streamable and storable.
Definition: TParameter.h:37
const AParamType & GetVal() const
Definition: TParameter.h:69
Class to steer the merging of files produced on the workers.
Random number generator class based on M.
Definition: TRandom3.h:27
Basic string class.
Definition: TString.h:131
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1371
A TTree represents a columnar dataset.
Definition: TTree.h:71
This class represents a WWW compatible URL.
Definition: TUrl.h:35
return c1
Definition: legend1.C:41
return c2
Definition: legend2.C:14
void Begin(Int_t type)
static constexpr double s
Double_t Sqrt(Double_t x)
Definition: TMath.h:679