Logo ROOT  
Reference Guide
TFoam.cxx
Go to the documentation of this file.
1// @(#)root/foam:$Id$
2// Author: S. Jadach <mailto:Stanislaw.jadach@ifj.edu.pl>, P.Sawicki <mailto:Pawel.Sawicki@ifj.edu.pl>
3
4/** \class TFoam
5
6
7TFoam is the main class of the multi-dimensional general purpose
8Monte Carlo event generator (integrator) FOAM.
9
10### FOAM Version 1.02M
11
12\authors
13 S. Jadach and P.Sawicki
14 Institute of Nuclear Physics, Cracow, Poland
15 Stanislaw. Jadach@ifj.edu.pl, Pawel.Sawicki@ifj.edu.pl
16
17### What is FOAM for?
18
19 - Suppose you want to generate randomly points (vectors) according to
20 an arbitrary probability distribution in n dimensions,
21 for which you supply your own method. FOAM can do it for you!
22 Even if your distributions has quite strong peaks and is discontinuous!
23- FOAM generates random points with weight one or with variable weight.
24 - FOAM is capable to integrate using efficient "adaptive" MC method.
25 (The distribution does not need to be normalized to one.)
26
27### How does it work?
28
29FOAM is the simplified version of the multi-dimensional general purpose
30Monte Carlo event generator (integrator) FOAM.
31It creates hyper-rectangular "foam of cells", which is more dense around its peaks.
32See the following 2-dim. example of the map of 1000 cells for doubly peaked distribution:
33
34\image html foam_MapCamel1000.png width=400
35
36FOAM is now fully integrated with the ROOT package.
37The important bonus of the ROOT use is persistency of the FOAM objects!
38
39For more sophisticated problems full version of FOAM may be more appropriate:
40See [full version of FOAM](http://jadach.home.cern.ch/jadach/Foam/Index.html)
41
42### Simple example of the use of FOAM:
43
44Begin_Macro(source)
45../../../tutorials/foam/foam_kanwa.C
46End_Macro
47
48### Canonical nine steering parameters of FOAM
49
50
51| Name | default | Description |
52|----------|----------|--------------------------------------------------------|
53| kDim | 0 | Dimension of the integration space. Must be redefined! |
54| nCells | 1000 | No of allocated number of cells, |
55| nSampl | 200 | No. of MC events in the cell MC exploration |
56| nBin | 8 | No. of bins in edge-histogram in cell exploration |
57| OptRej | 1 | OptRej = 0, weighted; OptRej=1, wt=1 MC events |
58| OptDrive | 2 | Maximum weight reduction, =1 for variance reduction |
59| EvPerBin | 25 | Maximum number of the effective wt=1 events/bin, |
60| | | EvPerBin=0 deactivates this option |
61| Chat | 1 | =0,1,2 is the ``chat level'' in the standard output |
62| MaxWtRej | 1.1 | Maximum weight used to get w=1 MC events |
63
64The above can be redefined before calling Initialize() method,
65for instance `FoamObject->SetkDim(15)` sets dimension of the distribution to 15.
66Only `kDim` HAS TO BE redefined, the other parameters may be left at their defaults.
67`nCell` may be increased up to about million cells for wildly peaked distributions.
68Increasing `nSampl` sometimes helps, but it may cost CPU time.
69`MaxWtRej` may need to be increased for wild a distribution, while using `OptRej=0`.
70
71Past versions of FOAM: August 2003, v.1.00; September 2003 v.1.01
72Adopted starting from FOAM-2.06 by P. Sawicki
73
74Users of FOAM are kindly requested to cite the following work:
75S. Jadach, Computer Physics Communications 152 (2003) 55.
76
77*/
78
79#include "TFoam.h"
80#include "TFoamIntegrand.h"
81#include "TFoamMaxwt.h"
82#include "TFoamVect.h"
83#include "TFoamCell.h"
84#include "Riostream.h"
85#include "TH1.h"
86#include "TObjArray.h"
87#include "TMethodCall.h"
88#include "TRandom.h"
89#include "TMath.h"
90#include "TInterpreter.h"
91
93
94//FFFFFF BoX-FORMATs for nice and flexible outputs
95#define BXOPE std::cout<<\
96"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"<<std::endl<<\
97"F F"<<std::endl
98#define BXTXT(text) std::cout<<\
99"F "<<std::setw(40)<< text <<" F"<<std::endl
100#define BX1I(name,numb,text) std::cout<<\
101"F "<<std::setw(10)<<name<<" = "<<std::setw(10)<<numb<<" = " <<std::setw(50)<<text<<" F"<<std::endl
102#define BX1F(name,numb,text) std::cout<<"F "<<std::setw(10)<<name<<\
103 " = "<<std::setw(15)<<std::setprecision(8)<<numb<<" = "<<std::setw(40)<<text<<" F"<<std::endl
104#define BX2F(name,numb,err,text) std::cout<<"F "<<std::setw(10)<<name<<\
105" = "<<std::setw(15)<<std::setprecision(8)<<numb<<" +- "<<std::setw(15)<<std::setprecision(8)<<err<< \
106 " = "<<std::setw(25)<<text<<" F"<<std::endl
107#define BXCLO std::cout<<\
108"F F"<<std::endl<<\
109"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"<<std::endl
110 //FFFFFF BoX-FORMATs ends here
111
112static const Double_t gHigh= 1.0e150;
113static const Double_t gVlow=-1.0e150;
114
115#define SW2 setprecision(7) << std::setw(12)
116
117// class to wrap a global function in a TFoamIntegrand function
118class FoamIntegrandFunction : public TFoamIntegrand {
119
120public:
121
122 typedef Double_t (*FunctionPtr)(Int_t, Double_t*);
123
124 FoamIntegrandFunction(FunctionPtr func) : fFunc(func) {}
125
126 virtual ~FoamIntegrandFunction() {}
127
128 // evaluate the density using the provided function pointer
129 Double_t Density (Int_t nDim, Double_t * x) {
130 return fFunc(nDim,x);
131 }
132
133private:
134
135 FunctionPtr fFunc;
136
137};
138
139
140////////////////////////////////////////////////////////////////////////////////
141/// Default constructor for streamer, user should not use it.
142
144 fDim(0), fNCells(0), fRNmax(0),
145 fOptDrive(0), fChat(0), fOptRej(0),
146 fNBin(0), fNSampl(0), fEvPerBin(0),
147 fMaskDiv(0), fInhiDiv(0), fOptPRD(0), fXdivPRD(0),
148 fNoAct(0), fLastCe(0), fCells(0),
149 fMCMonit(0), fMaxWtRej(0), fPrimAcu(0),
150 fHistEdg(0), fHistDbg(0), fHistWt(0),
151 fMCvect(0), fMCwt(0), fRvec(0),
152 fRho(0), fMethodCall(0), fPseRan(0),
153 fNCalls(0), fNEffev(0),
154 fSumWt(0), fSumWt2(0),
155 fSumOve(0), fNevGen(0),
156 fWtMax(0), fWtMin(0),
157 fPrime(0), fMCresult(0), fMCerror(0),
158 fAlpha(0)
159{
160}
161////////////////////////////////////////////////////////////////////////////////
162/// User constructor, to be employed by the user
163
165 fDim(0), fNCells(0), fRNmax(0),
166 fOptDrive(0), fChat(0), fOptRej(0),
167 fNBin(0), fNSampl(0), fEvPerBin(0),
168 fMaskDiv(0), fInhiDiv(0), fOptPRD(0), fXdivPRD(0),
169 fNoAct(0), fLastCe(0), fCells(0),
170 fMCMonit(0), fMaxWtRej(0), fPrimAcu(0),
171 fHistEdg(0), fHistDbg(0), fHistWt(0),
172 fMCvect(0), fMCwt(0), fRvec(0),
173 fRho(0), fMethodCall(0), fPseRan(0),
174 fNCalls(0), fNEffev(0),
175 fSumWt(0), fSumWt2(0),
176 fSumOve(0), fNevGen(0),
177 fWtMax(0), fWtMin(0),
178 fPrime(0), fMCresult(0), fMCerror(0),
179 fAlpha(0)
180{
181 if(strlen(Name) >129) {
182 Error("TFoam","Name too long %s \n",Name);
183 }
184 fName=Name; // Class name
185 fDate=" Release date: 2005.04.10"; // Release date
186 fVersion= "1.02M"; // Release version
187 fMaskDiv = 0; // Dynamic Mask for cell division, h-cubic
188 fInhiDiv = 0; // Flag allowing to inhibit cell division in certain projection/edge
189 fXdivPRD = 0; // Lists of division values encoded in one vector per direction
190 fCells = 0;
191 fAlpha = 0;
192 fPrimAcu = 0;
193 fHistEdg = 0;
194 fHistWt = 0;
195 fHistDbg = 0;
196 fDim = 0; // dimension of hyp-cubical space
197 fNCells = 1000; // Maximum number of Cells, is usually re-set
198 fNSampl = 200; // No of sampling when dividing cell
199 fOptPRD = 0; // General Option switch for PRedefined Division, for quick check
200 fOptDrive = 2; // type of Drive =1,2 for TrueVol,Sigma,WtMax
201 fChat = 1; // Chat=0,1,2 chat level in output, Chat=1 normal level
202 fOptRej = 1; // OptRej=0, wted events; OptRej=1, wt=1 events
203 /////////////////////////////////////////////////////////////////////////////
204
205 fNBin = 8; // binning of edge-histogram in cell exploration
206 fEvPerBin =25; // maximum no. of EFFECTIVE event per bin, =0 option is inactive
207 //------------------------------------------------------
208 fNCalls = 0; // No of function calls
209 fNEffev = 0; // Total no of eff. wt=1 events in build=up
210 fLastCe =-1; // Index of the last cell
211 fNoAct = 0; // No of active cells (used in MC generation)
212 fWtMin = gHigh; // Minimal weight
213 fWtMax = gVlow; // Maximal weight
214 fMaxWtRej =1.10; // Maximum weight in rejection for getting wt=1 events
215 fPseRan = 0; // Initialize private copy of random number generator
216 fMCMonit = 0; // MC efficiency monitoring
217 fRho = 0; // pointer to abstract class providing function to integrate
218 fMCvect = 0;
219 fRvec = 0;
220 fPseRan = 0; // generator of pseudorandom numbers
221 fMethodCall=0; // ROOT's pointer to global distribution function
222}
223
224////////////////////////////////////////////////////////////////////////////////
225/// Default destructor
226
228{
229 Int_t i;
230
231 if(fCells!= 0) {
232 for(i=0; i<fNCells; i++) delete fCells[i]; // TFoamCell*[]
233 delete [] fCells;
234 }
235 if (fRvec) delete [] fRvec; //double[]
236 if (fAlpha) delete [] fAlpha; //double[]
237 if (fMCvect) delete [] fMCvect; //double[]
238 if (fPrimAcu) delete [] fPrimAcu; //double[]
239 if (fMaskDiv) delete [] fMaskDiv; //int[]
240 if (fInhiDiv) delete [] fInhiDiv; //int[]
241
242 if( fXdivPRD!= 0) {
243 for(i=0; i<fDim; i++) delete fXdivPRD[i]; // TFoamVect*[]
244 delete [] fXdivPRD;
245 }
246 if (fMCMonit) delete fMCMonit;
247 if (fHistWt) delete fHistWt;
248
249 // delete histogram arrays
250 if (fHistEdg) {
251 fHistEdg->Delete();
252 delete fHistEdg;
253 }
254 if (fHistDbg) {
255 fHistDbg->Delete();
256 delete fHistDbg;
257 }
258 // delete function object if it has been created here in SetRhoInt
259 if (fRho && dynamic_cast<FoamIntegrandFunction*>(fRho) ) delete fRho;
260}
261
262
263////////////////////////////////////////////////////////////////////////////////
264/// Copy Constructor NOT IMPLEMENTED (NEVER USED)
265
266TFoam::TFoam(const TFoam &From): TObject(From)
267{
268 Error("TFoam", "COPY CONSTRUCTOR NOT IMPLEMENTED \n");
269}
270
271////////////////////////////////////////////////////////////////////////////////
272/// ### Basic initialization of FOAM invoked by the user. Mandatory!
273///
274/// This method starts the process of the cell build-up.
275/// User must invoke Initialize with two arguments or Initialize without arguments.
276/// This is done BEFORE generating first MC event and AFTER allocating FOAM object
277/// and reseting (optionally) its internal parameters/switches.
278/// The overall operational scheme of the FOAM is the following:
279///
280/// \image html foam_schema2.png width=600
281///
282/// ### This method invokes several other methods:
283///
284/// InitCells initializes memory storage for cells and begins exploration process
285/// from the root cell. The empty cells are allocated/filled using CellFill.
286/// The procedure Grow which loops over cells, picks up the cell with the biggest
287/// ``driver integral'', see Comp. Phys. Commun. 152 152 (2003) 55 for explanations,
288/// with the help of PeekMax procedure. The chosen cell is split using Divide.
289/// Subsequently, the procedure Explore called by the Divide
290/// (and by InitCells for the root cell) does the most important
291/// job in the FOAM object build-up: it performs a small MC run for each
292/// newly allocated daughter cell.
293/// Explore calculates how profitable the future split of the cell will be
294/// and defines the optimal cell division geometry with the help of Carver or Varedu
295/// procedures, for maximum weight or variance optimization respectively.
296/// All essential results of the exploration are written into
297/// the explored cell object. At the very end of the foam build-up,
298/// Finally, MakeActiveList is invoked to create a list of pointers to
299/// all active cells, for the purpose of the quick access during the MC generation.
300/// The procedure Explore employs MakeAlpha to generate random coordinates
301/// inside a given cell with the uniform distribution.
302/// The above sequence of the procedure calls is depicted in the following figure:
303///
304/// \image html foam_Initialize_schema.png width=600
305
307{
308
309
310 SetPseRan(PseRan);
311 SetRho(fun);
312 Initialize();
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Basic initialization of FOAM invoked by the user.
317/// IMPORTANT: Random number generator and the distribution object has to be
318/// provided using SetPseRan and SetRho prior to invoking this initialiser!
319
321{
322 Bool_t addStatus = TH1::AddDirectoryStatus();
324 Int_t i;
325
326 if(fChat>0){
327 BXOPE;
328 BXTXT("****************************************");
329 BXTXT("****** TFoam::Initialize ******");
330 BXTXT("****************************************");
331 BXTXT(fName);
332 BX1F(" Version",fVersion, fDate);
333 BX1I(" kDim",fDim, " Dimension of the hyper-cubical space ");
334 BX1I(" nCells",fNCells, " Requested number of Cells (half of them active) ");
335 BX1I(" nSampl",fNSampl, " No of MC events in exploration of a cell ");
336 BX1I(" nBin",fNBin, " No of bins in histograms, MC exploration of cell ");
337 BX1I(" EvPerBin",fEvPerBin, " Maximum No effective_events/bin, MC exploration ");
338 BX1I(" OptDrive",fOptDrive, " Type of Driver =1,2 for Sigma,WtMax ");
339 BX1I(" OptRej",fOptRej, " MC rejection on/off for OptRej=0,1 ");
340 BX1F(" MaxWtRej",fMaxWtRej, " Maximum wt in rejection for wt=1 evts");
341 BXCLO;
342 }
343
344 if(fPseRan==0) Error("Initialize", "Random number generator not set \n");
345 if(fRho==0 && fMethodCall==0 ) Error("Initialize", "Distribution function not set \n");
346 if(fDim==0) Error("Initialize", "Zero dimension not allowed \n");
347
348 /////////////////////////////////////////////////////////////////////////
349 // ALLOCATE SMALL LISTS //
350 // it is done globally, not for each cell, to save on allocation time //
351 /////////////////////////////////////////////////////////////////////////
352 fRNmax= fDim+1;
353 fRvec = new Double_t[fRNmax]; // Vector of random numbers
354 if(fRvec==0) Error("Initialize", "Cannot initialize buffer fRvec \n");
355
356 if(fDim>0){
357 fAlpha = new Double_t[fDim]; // sum<1 for internal parametrization of the simplex
358 if(fAlpha==0) Error("Initialize", "Cannot initialize buffer fAlpha \n" );
359 }
360 fMCvect = new Double_t[fDim]; // vector generated in the MC run
361 if(fMCvect==0) Error("Initialize", "Cannot initialize buffer fMCvect \n" );
362
363 //====== List of directions inhibited for division
364 if(fInhiDiv == 0){
365 fInhiDiv = new Int_t[fDim];
366 for(i=0; i<fDim; i++) fInhiDiv[i]=0;
367 }
368 //====== Dynamic mask used in Explore for edge determination
369 if(fMaskDiv == 0){
370 fMaskDiv = new Int_t[fDim];
371 for(i=0; i<fDim; i++) fMaskDiv[i]=1;
372 }
373 //====== List of predefined division values in all directions (initialized as empty)
374 if(fXdivPRD == 0){
375 fXdivPRD = new TFoamVect*[fDim];
376 for(i=0; i<fDim; i++) fXdivPRD[i]=0; // Artificially extended beyond fDim
377 }
378 //====== Initialize list of histograms
379 fHistWt = new TH1D("HistWt","Histogram of MC weight",100,0.0, 1.5*fMaxWtRej); // MC weight
380 fHistEdg = new TObjArray(fDim); // Initialize list of histograms
381 TString hname;
382 TString htitle;
383 for(i=0;i<fDim;i++){
384 hname=fName+TString("_HistEdge_");
385 hname+=i;
386 htitle=TString("Edge Histogram No. ");
387 htitle+=i;
388 //std::cout<<"i= "<<i<<" hname= "<<hname<<" htitle= "<<htitle<<std::endl;
389 (*fHistEdg)[i] = new TH1D(hname.Data(),htitle.Data(),fNBin,0.0, 1.0); // Initialize histogram for each edge
390 ((TH1D*)(*fHistEdg)[i])->Sumw2();
391 }
392 //====== extra histograms for debug purposes
393 fHistDbg = new TObjArray(fDim); // Initialize list of histograms
394 for(i=0;i<fDim;i++){
395 hname=fName+TString("_HistDebug_");
396 hname+=i;
397 htitle=TString("Debug Histogram ");
398 htitle+=i;
399 (*fHistDbg)[i] = new TH1D(hname.Data(),htitle.Data(),fNBin,0.0, 1.0); // Initialize histogram for each edge
400 }
401
402 // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //
403 // BUILD-UP of the FOAM //
404 // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //
405 //
406 // Define and explore root cell(s)
407 InitCells();
408 // PrintCells(); std::cout<<" ===== after InitCells ====="<<std::endl;
409 Grow();
410 // PrintCells(); std::cout<<" ===== after Grow ====="<<std::endl;
411
412 MakeActiveList(); // Final Preparations for the M.C. generation
413
414 // Preparations for the M.C. generation
415 fSumWt = 0.0; // M.C. generation sum of Wt
416 fSumWt2 = 0.0; // M.C. generation sum of Wt**2
417 fSumOve = 0.0; // M.C. generation sum of overweighted
418 fNevGen = 0.0; // M.C. generation sum of 1d0
419 fWtMax = gVlow; // M.C. generation maximum wt
420 fWtMin = gHigh; // M.C. generation minimum wt
421 fMCresult=fCells[0]->GetIntg(); // M.C. Value of INTEGRAL,temporary assignment
422 fMCresult=fCells[0]->GetIntg(); // M.C. Value of INTEGRAL,temporary assignment
423 fMCerror =fCells[0]->GetIntg(); // M.C. Value of ERROR ,temporary assignment
424 fMCMonit = new TFoamMaxwt(5.0,1000); // monitoring M.C. efficiency
425 //
426 if(fChat>0){
427 Double_t driver = fCells[0]->GetDriv();
428 BXOPE;
429 BXTXT("*** TFoam::Initialize FINISHED!!! ***");
430 BX1I(" nCalls",fNCalls, "Total number of function calls ");
431 BX1F(" XPrime",fPrime, "Primary total integral ");
432 BX1F(" XDiver",driver, "Driver total integral ");
433 BX1F(" mcResult",fMCresult,"Estimate of the true MC Integral ");
434 BXCLO;
435 }
436 if(fChat==2) PrintCells();
437 TH1::AddDirectory(addStatus);
438} // Initialize
439
440////////////////////////////////////////////////////////////////////////////////
441/// Internal method used by Initialize.
442/// It initializes "root part" of the FOAM of the tree of cells.
443
445{
446 Int_t i;
447
448 fLastCe =-1; // Index of the last cell
449 if(fCells!= 0) {
450 for(i=0; i<fNCells; i++) delete fCells[i];
451 delete [] fCells;
452 }
453 //
454 fCells = new TFoamCell*[fNCells];
455 for(i=0;i<fNCells;i++){
456 fCells[i]= new TFoamCell(fDim); // Allocate BIG list of cells
457 fCells[i]->SetSerial(i);
458 }
459 if(fCells==0) Error("InitCells", "Cannot initialize CELLS \n" );
460
461 /////////////////////////////////////////////////////////////////////////////
462 // Single Root Hypercube //
463 /////////////////////////////////////////////////////////////////////////////
464 CellFill(1, 0); // 0-th cell ACTIVE
465
466 // Exploration of the root cell(s)
467 for(Long_t iCell=0; iCell<=fLastCe; iCell++){
468 Explore( fCells[iCell] ); // Exploration of root cell(s)
469 }
470}
471
472////////////////////////////////////////////////////////////////////////////////
473/// Internal method used by Initialize.
474/// It initializes content of the newly allocated active cell.
475
477{
478 TFoamCell *cell;
479 if (fLastCe==fNCells){
480 Error( "CellFill", "Too many cells\n");
481 }
482 fLastCe++; // 0-th cell is the first
483 if (Status==1) fNoAct++;
484
485 cell = fCells[fLastCe];
486
487 cell->Fill(Status, parent, 0, 0);
488
489 cell->SetBest( -1); // pointer for planning division of the cell
490 cell->SetXdiv(0.5); // factor for division
491 Double_t xInt2,xDri2;
492 if(parent!=0){
493 xInt2 = 0.5*parent->GetIntg();
494 xDri2 = 0.5*parent->GetDriv();
495 cell->SetIntg(xInt2);
496 cell->SetDriv(xDri2);
497 }else{
498 cell->SetIntg(0.0);
499 cell->SetDriv(0.0);
500 }
501 return fLastCe;
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Internal method used by Initialize.
506///
507/// It explores newly defined cell with help of special short MC sampling.
508/// As a result, estimates of true and drive volume is defined/determined
509/// Average and dispersion of the weight distribution will is found along
510/// each edge and the best edge (minimum dispersion, best maximum weight)
511/// is memorized for future use.
512///
513/// The optimal division point for eventual future cell division is
514/// determined/recorded. Recorded are also minimum and maximum weight etc.
515/// The volume estimate in all (inactive) parent cells is updated.
516/// Note that links to parents and initial volume = 1/2 parent has to be
517/// already defined prior to calling this routine.
518
520{
521 Double_t wt, dx, xBest=0, yBest=0;
522 Double_t intOld, driOld;
523
524 Long_t iev;
525 Double_t nevMC;
526 Int_t i, j, k;
527 Int_t nProj, kBest;
528 Double_t ceSum[5], xproj;
529
530 TFoamVect cellSize(fDim);
531 TFoamVect cellPosi(fDim);
532
533 cell->GetHcub(cellPosi,cellSize);
534
535 TFoamCell *parent;
536
537 Double_t *xRand = new Double_t[fDim];
538
539 Double_t *volPart=0;
540
541 cell->CalcVolume();
542 dx = cell->GetVolume();
543 intOld = cell->GetIntg(); //memorize old values,
544 driOld = cell->GetDriv(); //will be needed for correcting parent cells
545
546
547 /////////////////////////////////////////////////////
548 // Special Short MC sampling to probe cell //
549 /////////////////////////////////////////////////////
550 ceSum[0]=0;
551 ceSum[1]=0;
552 ceSum[2]=0;
553 ceSum[3]=gHigh; //wtmin
554 ceSum[4]=gVlow; //wtmax
555 //
556 for(i=0;i<fDim;i++) ((TH1D *)(*fHistEdg)[i])->Reset(); // Reset histograms
557 fHistWt->Reset();
558 //
559 // ||||||||||||||||||||||||||BEGIN MC LOOP|||||||||||||||||||||||||||||
560 Double_t nevEff=0.;
561 for(iev=0;iev<fNSampl;iev++){
562 MakeAlpha(); // generate uniformly vector inside hypercube
563
564 if(fDim>0){
565 for(j=0; j<fDim; j++)
566 xRand[j]= cellPosi[j] +fAlpha[j]*(cellSize[j]);
567 }
568
569 wt=dx*Eval(xRand);
570
571 nProj = 0;
572 if(fDim>0) {
573 for(k=0; k<fDim; k++) {
574 xproj =fAlpha[k];
575 ((TH1D *)(*fHistEdg)[nProj])->Fill(xproj,wt);
576 nProj++;
577 }
578 }
579 //
580 fNCalls++;
581 ceSum[0] += wt; // sum of weights
582 ceSum[1] += wt*wt; // sum of weights squared
583 ceSum[2]++; // sum of 1
584 if (ceSum[3]>wt) ceSum[3]=wt; // minimum weight;
585 if (ceSum[4]<wt) ceSum[4]=wt; // maximum weight
586 // test MC loop exit condition
587 nevEff = ceSum[1] == 0. ? 0. : ceSum[0]*ceSum[0]/ceSum[1];
588 if( nevEff >= fNBin*fEvPerBin) break;
589 } // ||||||||||||||||||||||||||END MC LOOP|||||||||||||||||||||||||||||
590 //------------------------------------------------------------------
591 //--- predefine logics of searching for the best division edge ---
592 for(k=0; k<fDim;k++){
593 fMaskDiv[k] =1; // default is all
594 if( fInhiDiv[k]==1) fMaskDiv[k] =0; // inhibit some...
595 }
596 // Note that predefined division below overrule inhibition above
597 kBest=-1;
598 Double_t rmin,rmax,rdiv;
599 if(fOptPRD) { // quick check
600 for(k=0; k<fDim; k++) {
601 rmin= cellPosi[k];
602 rmax= cellPosi[k] +cellSize[k];
603 if( fXdivPRD[k] != 0) {
604 Int_t n= (fXdivPRD[k])->GetDim();
605 for(j=0; j<n; j++) {
606 rdiv=(*fXdivPRD[k])[j];
607 // check predefined divisions is available in this cell
608 if( (rmin +1e-99 <rdiv) && (rdiv< rmax -1e-99)) {
609 kBest=k;
610 xBest= (rdiv-cellPosi[k])/cellSize[k] ;
611 goto ee05;
612 }
613 }
614 }
615 }//k
616 }
617 ee05:
618 /////////////////////////////////////////////////////////////////////////////
619
620 fNEffev += (Long_t)nevEff;
621 nevMC = ceSum[2];
622 Double_t intTrue = ceSum[0]/(nevMC+0.000001);
623 Double_t intDriv=0.;
624 Double_t intPrim=0.;
625
626 switch(fOptDrive){
627 case 1: // VARIANCE REDUCTION
628 if(kBest == -1) Varedu(ceSum,kBest,xBest,yBest); // determine the best edge,
629 //intDriv =sqrt( ceSum[1]/nevMC -intTrue*intTrue ); // Older ansatz, numerically not bad
630 intDriv =sqrt(ceSum[1]/nevMC) -intTrue; // Foam build-up, sqrt(<w**2>) -<w>
631 intPrim =sqrt(ceSum[1]/nevMC); // MC gen. sqrt(<w**2>) =sqrt(<w>**2 +sigma**2)
632 break;
633 case 2: // WTMAX REDUCTION
634 if(kBest == -1) Carver(kBest,xBest,yBest); // determine the best edge
635 intDriv =ceSum[4] -intTrue; // Foam build-up, wtmax-<w>
636 intPrim =ceSum[4]; // MC generation, wtmax!
637 break;
638 default:
639 Error("Explore", "Wrong fOptDrive = \n" );
640 }//switch
641 //=================================================================================
642 //hist_Neff_distrib.Fill( fLastCe/2.0+0.01, nevEff+0.01); //
643 //hist_kBest_distrib.Fill( kBest+0.50, 1.0 ); // debug
644 //hist_xBest_distrib.Fill( xBest+0.01, 1.0 ); // debug
645 //=================================================================================
646 cell->SetBest(kBest);
647 cell->SetXdiv(xBest);
648 cell->SetIntg(intTrue);
649 cell->SetDriv(intDriv);
650 cell->SetPrim(intPrim);
651 // correct/update integrals in all parent cells to the top of the tree
652 Double_t parIntg, parDriv;
653 for(parent = cell->GetPare(); parent!=0; parent = parent->GetPare()){
654 parIntg = parent->GetIntg();
655 parDriv = parent->GetDriv();
656 parent->SetIntg( parIntg +intTrue -intOld );
657 parent->SetDriv( parDriv +intDriv -driOld );
658 }
659 delete [] volPart;
660 delete [] xRand;
661 //cell->Print();
662} // TFoam::Explore
663
664////////////////////////////////////////////////////////////////////////////////
665/// Internal method used by Initialize.
666///
667/// It determines the best edge candidate and the position of the cell division plane
668/// in case of the variance reduction for future cell division,
669/// using results of the MC exploration run stored in fHistEdg
670
671void TFoam::Varedu(Double_t ceSum[5], Int_t &kBest, Double_t &xBest, Double_t &yBest)
672{
673 Double_t nent = ceSum[2];
674 Double_t swAll = ceSum[0];
675 Double_t sswAll = ceSum[1];
676 Double_t ssw = sqrt(sswAll)/sqrt(nent);
677 //
678 Double_t swIn,swOut,sswIn,sswOut,xLo,xUp;
679 kBest =-1;
680 xBest =0.5;
681 yBest =1.0;
682 Double_t maxGain=0.0;
683 // Now go over all projections kProj
684 for(Int_t kProj=0; kProj<fDim; kProj++) {
685 if( fMaskDiv[kProj]) {
686 // initialize search over bins
687 Double_t sigmIn =0.0; Double_t sigmOut =0.0;
688 Double_t sswtBest = gHigh;
689 Double_t gain =0.0;
690 Double_t xMin=0.0; Double_t xMax=0.0;
691 // Double loop over all pairs jLo<jUp
692 for(Int_t jLo=1; jLo<=fNBin; jLo++) {
693 Double_t aswIn=0; Double_t asswIn=0;
694 for(Int_t jUp=jLo; jUp<=fNBin;jUp++) {
695 aswIn += ((TH1D *)(*fHistEdg)[kProj])->GetBinContent(jUp);
696 asswIn += Sqr(((TH1D *)(*fHistEdg)[kProj])->GetBinError( jUp));
697 xLo=(jLo-1.0)/fNBin;
698 xUp=(jUp*1.0)/fNBin;
699 swIn = aswIn/nent;
700 swOut = (swAll-aswIn)/nent;
701 sswIn = sqrt(asswIn) /sqrt(nent*(xUp-xLo)) *(xUp-xLo);
702 sswOut= sqrt(sswAll-asswIn)/sqrt(nent*(1.0-xUp+xLo)) *(1.0-xUp+xLo);
703 if( (sswIn+sswOut) < sswtBest) {
704 sswtBest = sswIn+sswOut;
705 gain = ssw-sswtBest;
706 sigmIn = sswIn -swIn; // Debug
707 sigmOut = sswOut-swOut; // Debug
708 xMin = xLo;
709 xMax = xUp;
710 }
711 }//jUp
712 }//jLo
713 Int_t iLo = (Int_t) (fNBin*xMin);
714 Int_t iUp = (Int_t) (fNBin*xMax);
715 //----------DEBUG printout
716 //std::cout<<"@@@@@ xMin xMax = "<<xMin <<" "<<xMax<<" iLo= "<<iLo<<" iUp= "<<iUp;
717 //std::cout<<" sswtBest/ssw= "<<sswtBest/ssw<<" Gain/ssw= "<< Gain/ssw<<std::endl;
718 //----------DEBUG auxiliary Plot
719 for(Int_t iBin=1;iBin<=fNBin;iBin++) {
720 if( ((iBin-0.5)/fNBin > xMin) && ((iBin-0.5)/fNBin < xMax) ){
721 ((TH1D *)(*fHistDbg)[kProj])->SetBinContent(iBin,sigmIn/(xMax-xMin));
722 } else {
723 ((TH1D *)(*fHistDbg)[kProj])->SetBinContent(iBin,sigmOut/(1-xMax+xMin));
724 }
725 }
726 if(gain>=maxGain) {
727 maxGain=gain;
728 kBest=kProj; // <--- !!!!! The best edge
729 xBest=xMin;
730 yBest=xMax;
731 if(iLo == 0) xBest=yBest; // The best division point
732 if(iUp == fNBin) yBest=xBest; // this is not really used
733 }
734 }
735 } //kProj
736 //----------DEBUG printout
737 //std::cout<<"@@@@@@@>>>>> kBest= "<<kBest<<" maxGain/ssw= "<< maxGain/ssw<<std::endl;
738 if( (kBest >= fDim) || (kBest<0) ) Error("Varedu", "Something wrong with kBest - kBest = %d dim = %d\n",kBest,fDim);
739} //TFoam::Varedu
740
741////////////////////////////////////////////////////////////////////////////////
742/// Internal method used by Initialize.
743///
744/// Determines the best edge-candidate and the position of the division plane
745/// for the future cell division, in the case of the optimization of the maximum weight.
746/// It exploits results of the cell MC exploration run stored in fHistEdg.
747
748void TFoam::Carver(Int_t &kBest, Double_t &xBest, Double_t &yBest)
749{
750 Int_t kProj,iBin;
751 Double_t carve,carvTot,carvMax,carvOne,binMax,binTot;
752 Int_t jLow,jUp,iLow,iUp;
753 Double_t theBin;
754 // Int_t jDivi; // TEST
755 Int_t j;
756
757 Double_t *bins = new Double_t[fNBin]; // bins of histogram for single PROJECTION
758 if(bins==0) Error("Carver", "Cannot initialize buffer Bins \n" );
759
760 kBest =-1;
761 xBest =0.5;
762 yBest =1.0;
763 carvMax = gVlow;
764 // primMax = gVlow;
765 for(kProj=0; kProj<fDim; kProj++)
766 if( fMaskDiv[kProj] ) {
767 //if( kProj==1 ){
768 //std::cout<<"==================== Carver histogram: kProj ="<<kProj<<"==================="<<std::endl;
769 //((TH1D *)(*fHistEdg)[kProj])->Print("all");
770 binMax = gVlow;
771 for(iBin=0; iBin<fNBin;iBin++){
772 bins[iBin]= ((TH1D *)(*fHistEdg)[kProj])->GetBinContent(iBin+1);
773 binMax = TMath::Max( binMax, bins[iBin]); // Maximum content/bin
774 }
775 if(binMax < 0 ) { //case of empty cell
776 delete [] bins;
777 return;
778 }
779 carvTot = 0.0;
780 binTot = 0.0;
781 for(iBin=0;iBin<fNBin;iBin++){
782 carvTot = carvTot + (binMax-bins[iBin]); // Total Carve (more stable)
783 binTot +=bins[iBin];
784 }
785 // primTot = binMax*fNBin;
786 //std::cout <<"Carver: CarvTot "<<CarvTot<< " primTot "<<primTot<<std::endl;
787 jLow =0;
788 jUp =fNBin-1;
789 carvOne = gVlow;
790 Double_t yLevel = gVlow;
791 for(iBin=0; iBin<fNBin;iBin++) {
792 theBin = bins[iBin];
793 //----- walk to the left and find first bin > theBin
794 iLow = iBin;
795 for(j=iBin; j>-1; j-- ) {
796 if(theBin< bins[j]) break;
797 iLow = j;
798 }
799 //iLow = iBin;
800 //if(iLow>0) while( (theBin >= bins[iLow-1])&&(iLow >0) ){iLow--;} // horror!!!
801 //------ walk to the right and find first bin > theBin
802 iUp = iBin;
803 for(j=iBin; j<fNBin; j++) {
804 if(theBin< bins[j]) break;
805 iUp = j;
806 }
807 //iUp = iBin;
808 //if(iUp<fNBin-1) while( (theBin >= bins[iUp+1])&&( iUp<fNBin-1 ) ){iUp++;} // horror!!!
809 //
810 carve = (iUp-iLow+1)*(binMax-theBin);
811 if( carve > carvOne) {
812 carvOne = carve;
813 jLow = iLow;
814 jUp = iUp;
815 yLevel = theBin;
816 }
817 }//iBin
818 if( carvTot > carvMax) {
819 carvMax = carvTot;
820 //primMax = primTot;
821 //std::cout <<"Carver: primMax "<<primMax<<std::endl;
822 kBest = kProj; // Best edge
823 xBest = ((Double_t)(jLow))/fNBin;
824 yBest = ((Double_t)(jUp+1))/fNBin;
825 if(jLow == 0 ) xBest = yBest;
826 if(jUp == fNBin-1) yBest = xBest;
827 // division ratio in units of 1/fNBin, testing
828 // jDivi = jLow;
829 // if(jLow == 0 ) jDivi=jUp+1;
830 }
831 //====== extra histograms for debug purposes
832 //std::cout<<"kProj= "<<kProj<<" jLow= "<<jLow<<" jUp= "<<jUp<<std::endl;
833 for(iBin=0; iBin<fNBin; iBin++)
834 ((TH1D *)(*fHistDbg)[kProj])->SetBinContent(iBin+1,binMax);
835 for(iBin=jLow; iBin<jUp+1; iBin++)
836 ((TH1D *)(*fHistDbg)[kProj])->SetBinContent(iBin+1,yLevel);
837 }//kProj
838 if( (kBest >= fDim) || (kBest<0) ) Error("Carver", "Something wrong with kBest - kBest = %d dim = %d\n",kBest,fDim);
839 delete [] bins;
840} //TFoam::Carver
841
842////////////////////////////////////////////////////////////////////////////////
843/// Internal method used by Initialize.
844/// Provides random vector Alpha 0< Alpha(i) < 1
845
847{
848 Int_t k;
849 if(fDim<1) return;
850
851 // simply generate and load kDim uniform random numbers
852 fPseRan->RndmArray(fDim,fRvec); // kDim random numbers needed
853 for(k=0; k<fDim; k++) fAlpha[k] = fRvec[k];
854} //MakeAlpha
855
856
857////////////////////////////////////////////////////////////////////////////////
858/// Internal method used by Initialize.
859/// It grow new cells by the binary division process.
860
862{
863 Long_t iCell;
864 TFoamCell* newCell;
865
866 while ( (fLastCe+2) < fNCells ) { // this condition also checked inside Divide
867 iCell = PeekMax(); // peek up cell with maximum driver integral
868 if( (iCell<0) || (iCell>fLastCe) ) {
869 Error("Grow", "Wrong iCell \n");
870 break;
871 }
872 newCell = fCells[iCell];
873
874 if(fLastCe !=0) {
875 Int_t kEcho=10;
876 if(fLastCe>=10000) kEcho=100;
877 if( (fLastCe%kEcho)==0) {
878 if (fChat>0) {
879 if(fDim<10)
880 std::cout<<fDim<<std::flush;
881 else
882 std::cout<<"."<<std::flush;
883 if( (fLastCe%(100*kEcho))==0) std::cout<<"|"<<fLastCe<<std::endl<<std::flush;
884 }
885 }
886 }
887 if( Divide( newCell )==0) break; // and divide it into two
888 }
889 if (fChat>0) {
890 std::cout<<std::endl<<std::flush;
891 }
892 CheckAll(0); // set arg=1 for more info
893}
894
895////////////////////////////////////////////////////////////////////////////////
896/// Internal method used by Initialize.
897/// It finds cell with maximal driver integral for the purpose of the division.
898
900{
901 Long_t i;
902 Long_t iCell = -1;
903 Double_t drivMax, driv;
904
905 drivMax = gVlow;
906 for(i=0; i<=fLastCe; i++) {//without root
907 if( fCells[i]->GetStat() == 1 ) {
908 driv = TMath::Abs( fCells[i]->GetDriv());
909 //std::cout<<"PeekMax: Driv = "<<driv<<std::endl;
910 if(driv > drivMax) {
911 drivMax = driv;
912 iCell = i;
913 }
914 }
915 }
916 // std::cout << 'TFoam_PeekMax: iCell=' << iCell << std::endl;
917 if (iCell == -1)
918 std::cout << "STOP in TFoam::PeekMax: not found iCell=" << iCell << std::endl;
919 return(iCell);
920} // TFoam_PeekMax
921
922////////////////////////////////////////////////////////////////////////////////
923/// Internal method used by Initialize.
924///
925/// It divides cell iCell into two daughter cells.
926/// The iCell is retained and tagged as inactive, daughter cells are appended
927/// at the end of the buffer.
928/// New vertex is added to list of vertices.
929/// List of active cells is updated, iCell removed, two daughters added
930/// and their properties set with help of MC sampling (TFoam_Explore)
931/// Returns Code RC=-1 of buffer limit is reached, fLastCe=fnBuf.
932
934{
935 Int_t kBest;
936
937 if(fLastCe+1 >= fNCells) Error("Divide", "Buffer limit is reached, fLastCe=fnBuf \n");
938
939 cell->SetStat(0); // reset cell as inactive
940 fNoAct--;
941
942 kBest = cell->GetBest();
943 if( kBest<0 || kBest>=fDim ) Error("Divide", "Wrong kBest \n");
944
945 //////////////////////////////////////////////////////////////////
946 // define two daughter cells (active) //
947 //////////////////////////////////////////////////////////////////
948
949 Int_t d1 = CellFill(1, cell);
950 Int_t d2 = CellFill(1, cell);
951 cell->SetDau0((fCells[d1]));
952 cell->SetDau1((fCells[d2]));
953 Explore( (fCells[d1]) );
954 Explore( (fCells[d2]) );
955 return 1;
956} // TFoam_Divide
957
958
959////////////////////////////////////////////////////////////////////////////////
960/// Internal method used by Initialize.
961///
962/// It finds out number of active cells fNoAct,
963/// creates list of active cell fCellsAct and primary cumulative fPrimAcu.
964/// They are used during the MC generation to choose randomly an active cell.
965
967{
968 Long_t iCell;
970 // flush previous result
971 if(fPrimAcu != 0) delete [] fPrimAcu;
972 fCellsAct.clear();
973 fCellsAct.reserve(fNoAct);
974
975 // Count Active cells and find total Primary
976 // Fill-in tables of active cells
977
978 fPrime = 0.0;
979 for(iCell=0; iCell<=fLastCe; iCell++) {
980 if (fCells[iCell]->GetStat()==1) {
981 fPrime += fCells[iCell]->GetPrim();
982 fCellsAct.push_back(iCell);
983 }
984 }
985
986 if(fNoAct != static_cast<Int_t>(fCellsAct.size())) Error("MakeActiveList", "Wrong fNoAct \n" );
987 if(fPrime == 0.) Error("MakeActiveList", "Integrand function is zero \n" );
988
989 fPrimAcu = new Double_t[fNoAct]; // cumulative primary for MC generation
990 if( fPrimAcu==0 ) Error("MakeActiveList", "Cant allocate fCellsAct or fPrimAcu \n");
991
992 sum =0.0;
993 for(iCell=0; iCell<fNoAct; iCell++) {
994 sum = sum + ( fCells[fCellsAct[iCell]] )->GetPrim()/fPrime;
995 fPrimAcu[iCell]=sum;
996 }
997
998} //MakeActiveList
999
1000////////////////////////////////////////////////////////////////////////////////
1001/// User may optionally reset random number generator using this method.
1002///
1003/// Usually it is done when FOAM object is restored from the disk.
1004/// IMPORTANT: this method deletes existing random number generator registered in the FOAM object.
1005/// In particular such an object is created by the streamer during the disk-read operation.
1006
1008{
1009 if(fPseRan) {
1010 Info("ResetPseRan", "Resetting random number generator \n");
1011 delete fPseRan;
1012 }
1013 SetPseRan(PseRan);
1014}
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// User may use this method to set the distribution object
1018
1020{
1021 if (fun)
1022 fRho=fun;
1023 else
1024 Error("SetRho", "Bad function \n" );
1025}
1026////////////////////////////////////////////////////////////////////////////////
1027/// User may use this method to set the distribution object as a global function pointer
1028/// (and not as an interpreted function).
1029
1031{
1032 // This is needed for both AClic and Cling
1033 if (fun) {
1034 // delete function object if it has been created here in SetRho
1035 if (fRho && dynamic_cast<FoamIntegrandFunction*>(fRho) ) delete fRho;
1036 fRho= new FoamIntegrandFunction(fun);
1037 } else
1038 Error("SetRho", "Bad function \n" );
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////
1042/// User may optionally reset the distribution using this method.
1043///
1044/// Usually it is done when FOAM object is restored from the disk.
1045/// IMPORTANT: this method deletes existing distribution object registered in the FOAM object.
1046/// In particular such an object is created by the streamer diring the disk-read operation.
1047/// This method is used only in very special cases, because the distribution in most cases
1048/// should be "owned" by the FOAM object and should not be replaced by another one after initialization.
1049
1051{
1052 if(fRho) {
1053 Info("ResetRho", "!!! Resetting distribution function !!!\n");
1054 delete fRho;
1055 }
1056 SetRho(fun);
1057}
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Internal method.
1061/// Evaluates distribution to be generated.
1062
1064{
1065 Double_t result;
1066
1067 if(!fRho) { //interactive mode
1068 Long_t paramArr[3];
1069 paramArr[0]=(Long_t)fDim;
1070 paramArr[1]=(Long_t)xRand;
1071 fMethodCall->SetParamPtrs(paramArr);
1072 fMethodCall->Execute(result);
1073 } else { //compiled mode
1074 result=fRho->Density(fDim,xRand);
1075 }
1076
1077 return result;
1078}
1079
1080////////////////////////////////////////////////////////////////////////////////
1081/// Internal method.
1082/// Return randomly chosen active cell with probability equal to its
1083/// contribution into total driver integral using interpolation search.
1084
1086{
1087 Long_t lo, hi, hit;
1088 Double_t fhit, flo, fhi;
1089 Double_t random;
1090
1091 random=fPseRan->Rndm();
1092 lo = 0; hi =fNoAct-1;
1093 flo = fPrimAcu[lo]; fhi=fPrimAcu[hi];
1094 while(lo+1<hi) {
1095 hit = lo + (Int_t)( (hi-lo)*(random-flo)/(fhi-flo)+0.5);
1096 if (hit<=lo)
1097 hit = lo+1;
1098 else if(hit>=hi)
1099 hit = hi-1;
1100 fhit=fPrimAcu[hit];
1101 if (fhit>random) {
1102 hi = hit;
1103 fhi = fhit;
1104 } else {
1105 lo = hit;
1106 flo = fhit;
1107 }
1108 }
1109 if (fPrimAcu[lo]>random)
1110 pCell = fCells[fCellsAct[lo]];
1111 else
1112 pCell = fCells[fCellsAct[hi]];
1113} // TFoam::GenerCel2
1114
1115
1116////////////////////////////////////////////////////////////////////////////////
1117/// User method.
1118/// It generates randomly point/vector according to user-defined distribution.
1119/// Prior initialization with help of Initialize() is mandatory.
1120/// Generated MC point/vector is available using GetMCvect and the MC weight with GetMCwt.
1121/// MC point is generated with wt=1 or with variable weight, see OptRej switch.
1122
1124{
1125 Int_t j;
1126 Double_t wt,dx,mcwt;
1127 TFoamCell *rCell;
1128 //
1129 //********************** MC LOOP STARS HERE **********************
1130ee0:
1131 GenerCel2(rCell); // choose randomly one cell
1132
1133 MakeAlpha();
1134
1135 TFoamVect cellPosi(fDim); TFoamVect cellSize(fDim);
1136 rCell->GetHcub(cellPosi,cellSize);
1137 for(j=0; j<fDim; j++)
1138 fMCvect[j]= cellPosi[j] +fAlpha[j]*cellSize[j];
1139 dx = rCell->GetVolume(); // Cartesian volume of the Cell
1140 // weight average normalized to PRIMARY integral over the cell
1141
1142 wt=dx*Eval(fMCvect);
1143
1144 mcwt = wt / rCell->GetPrim(); // PRIMARY controls normalization
1145 fNCalls++;
1146 fMCwt = mcwt;
1147 // accumulation of statistics for the main MC weight
1148 fSumWt += mcwt; // sum of Wt
1149 fSumWt2 += mcwt*mcwt; // sum of Wt**2
1150 fNevGen++; // sum of 1d0
1151 fWtMax = TMath::Max(fWtMax, mcwt); // maximum wt
1152 fWtMin = TMath::Min(fWtMin, mcwt); // minimum wt
1153 fMCMonit->Fill(mcwt);
1154 fHistWt->Fill(mcwt,1.0); // histogram
1155 //******* Optional rejection ******
1156 if(fOptRej == 1) {
1157 Double_t random;
1158 random=fPseRan->Rndm();
1159 if( fMaxWtRej*random > fMCwt) goto ee0; // Wt=1 events, internal rejection
1160 if( fMCwt<fMaxWtRej ) {
1161 fMCwt = 1.0; // normal Wt=1 event
1162 } else {
1163 fMCwt = fMCwt/fMaxWtRej; // weight for overweighted events! kept for debug
1164 fSumOve += fMCwt-fMaxWtRej; // contribution of overweighted
1165 }
1166 }
1167 //********************** MC LOOP ENDS HERE **********************
1168} // MakeEvent
1169
1170////////////////////////////////////////////////////////////////////////////////
1171/// User may get generated MC point/vector with help of this method
1172
1174{
1175 for ( Int_t k=0 ; k<fDim ; k++) *(MCvect +k) = fMCvect[k];
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179/// User may get weight MC weight using this method
1180
1182{
1183 return(fMCwt);
1184}
1185////////////////////////////////////////////////////////////////////////////////
1186/// User may get weight MC weight using this method
1187
1189{
1190 mcwt=fMCwt;
1191}
1192
1193////////////////////////////////////////////////////////////////////////////////
1194/// User method which generates MC event and returns MC weight
1195
1197{
1198 MakeEvent();
1199 GetMCvect(MCvect);
1200 return(fMCwt);
1201}
1202
1203////////////////////////////////////////////////////////////////////////////////
1204/// User method.
1205/// It provides the value of the integral calculated from the averages of the MC run
1206/// May be called after (or during) the MC run.
1207
1208void TFoam::GetIntegMC(Double_t &mcResult, Double_t &mcError)
1209{
1210 Double_t mCerelat;
1211 mcResult = 0.0;
1212 mCerelat = 1.0;
1213 if (fNevGen>0) {
1214 mcResult = fPrime*fSumWt/fNevGen;
1215 mCerelat = sqrt( fSumWt2/(fSumWt*fSumWt) - 1/fNevGen);
1216 }
1217 mcError = mcResult *mCerelat;
1218}
1219
1220////////////////////////////////////////////////////////////////////////////////
1221/// User method.
1222/// It returns NORMALIZATION integral to be combined with the average weights
1223/// and content of the histograms in order to get proper absolute normalization
1224/// of the integrand and distributions.
1225/// It can be called after initialization, before or during the MC run.
1226
1227void TFoam::GetIntNorm(Double_t& IntNorm, Double_t& Errel )
1228{
1229 if(fOptRej == 1) { // Wt=1 events, internal rejection
1230 Double_t intMC,errMC;
1231 GetIntegMC(intMC,errMC);
1232 IntNorm = intMC;
1233 Errel = errMC;
1234 } else { // Wted events, NO internal rejection
1235 IntNorm = fPrime;
1236 Errel = 0;
1237 }
1238}
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// May be called optionally after the MC run.
1242/// Returns various parameters of the MC weight for efficiency evaluation
1243
1245{
1246 Double_t mCeff, wtLim;
1247 fMCMonit->GetMCeff(eps, mCeff, wtLim);
1248 wtMax = wtLim;
1249 aveWt = fSumWt/fNevGen;
1250 sigma = sqrt( fSumWt2/fNevGen -aveWt*aveWt );
1251}
1252
1253////////////////////////////////////////////////////////////////////////////////
1254/// May be called optionally by the user after the MC run.
1255/// It provides normalization and also prints some information/statistics on the MC run.
1256
1257void TFoam::Finalize(Double_t& IntNorm, Double_t& Errel)
1258{
1259 GetIntNorm(IntNorm,Errel);
1260 Double_t mcResult,mcError;
1261 GetIntegMC(mcResult,mcError);
1262 Double_t mCerelat= mcError/mcResult;
1263 //
1264 if(fChat>0) {
1265 Double_t eps = 0.0005;
1266 Double_t mCeff, mcEf2, wtMax, aveWt, sigma;
1267 GetWtParams(eps, aveWt, wtMax, sigma);
1268 mCeff=0;
1269 if(wtMax>0.0) mCeff=aveWt/wtMax;
1270 mcEf2 = sigma/aveWt;
1271 Double_t driver = fCells[0]->GetDriv();
1272 //
1273 BXOPE;
1274 BXTXT("****************************************");
1275 BXTXT("****** TFoam::Finalize ******");
1276 BXTXT("****************************************");
1277 BX1I(" NevGen",fNevGen, "Number of generated events in the MC generation ");
1278 BX1I(" nCalls",fNCalls, "Total number of function calls ");
1279 BXTXT("----------------------------------------");
1280 BX1F(" AveWt",aveWt, "Average MC weight ");
1281 BX1F(" WtMin",fWtMin, "Minimum MC weight (absolute) ");
1282 BX1F(" WtMax",fWtMax, "Maximum MC weight (absolute) ");
1283 BXTXT("----------------------------------------");
1284 BX1F(" XPrime",fPrime, "Primary total integral, R_prime ");
1285 BX1F(" XDiver",driver, "Driver total integral, R_loss ");
1286 BXTXT("----------------------------------------");
1287 BX2F(" IntMC", mcResult, mcError, "Result of the MC Integral");
1288 BX1F(" mCerelat", mCerelat, "Relative error of the MC integral ");
1289 BX1F(" <w>/WtMax",mCeff, "MC efficiency, acceptance rate");
1290 BX1F(" Sigma/<w>",mcEf2, "MC efficiency, variance/ave_wt");
1291 BX1F(" WtMax",wtMax, "WtMax(esp= 0.0005) ");
1292 BX1F(" Sigma",sigma, "variance of MC weight ");
1293 if(fOptRej==1) {
1294 Double_t avOve=fSumOve/fSumWt;
1295 BX1F("<OveW>/<W>",avOve, "Contrib. of events wt>MaxWtRej");
1296 }
1297 BXCLO;
1298 }
1299} // Finalize
1300
1301////////////////////////////////////////////////////////////////////////////////
1302/// This can be called before Initialize, after setting kDim
1303/// It defines which variables are excluded in the process of the cell division.
1304/// For example 'FoamX->SetInhiDiv(1, 1);' inhibits division of y-variable.
1305/// The resulting map of cells in 2-dim. case will look as follows:
1306///
1307/// \image html foam_Map2.png width=400
1308
1309void TFoam::SetInhiDiv(Int_t iDim, Int_t InhiDiv)
1310{
1311
1312
1313 if(fDim==0) Error("TFoam","SetInhiDiv: fDim=0 \n");
1314 if(fInhiDiv == 0) {
1315 fInhiDiv = new Int_t[ fDim ];
1316 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
1317 }
1318 //
1319 if( ( 0<=iDim) && (iDim<fDim)) {
1320 fInhiDiv[iDim] = InhiDiv;
1321 } else
1322 Error("SetInhiDiv:","Wrong iDim \n");
1323}
1324
1325////////////////////////////////////////////////////////////////////////////////
1326/// This should be called before Initialize, after setting kDim
1327/// It predefines values of the cell division for certain variable iDim.
1328/// For example setting 3 predefined division lines using:
1329///
1330/// ~~~ {.cpp}
1331/// xDiv[0]=0.30; xDiv[1]=0.40; xDiv[2]=0.65;
1332/// FoamX->SetXdivPRD(0,3,xDiv);
1333/// ~~~
1334///
1335/// results in the following 2-dim. pattern of the cells:
1336///
1337/// \image html foam_Map3.png width=400
1338
1339void TFoam::SetXdivPRD(Int_t iDim, Int_t len, Double_t xDiv[])
1340{
1341 Int_t i;
1342
1343 if(fDim<=0) Error("SetXdivPRD", "fDim=0 \n");
1344 if( len<1 ) Error("SetXdivPRD", "len<1 \n");
1345 // allocate list of pointers, if it was not done before
1346 if(fXdivPRD == 0) {
1347 fXdivPRD = new TFoamVect*[fDim];
1348 for(i=0; i<fDim; i++) fXdivPRD[i]=0;
1349 }
1350 // set division list for direction iDim in H-cubic space!!!
1351 if( ( 0<=iDim) && (iDim<fDim)) {
1352 fOptPRD =1; // !!!!
1353 if( fXdivPRD[iDim] != 0)
1354 Error("SetXdivPRD", "Second allocation of XdivPRD not allowed \n");
1355 fXdivPRD[iDim] = new TFoamVect(len); // allocate list of division points
1356 for(i=0; i<len; i++) {
1357 (*fXdivPRD[iDim])[i]=xDiv[i]; // set list of division points
1358 }
1359 } else {
1360 Error("SetXdivPRD", "Wrong iDim \n");
1361 }
1362 // Printing predefined division points
1363 std::cout<<" SetXdivPRD, idim= "<<iDim<<" len= "<<len<<" "<<std::endl;
1364 for(i=0; i<len; i++) {
1365 if (iDim < fDim) std::cout<< (*fXdivPRD[iDim])[i] <<" ";
1366 }
1367 std::cout<<std::endl;
1368 for(i=0; i<len; i++) std::cout<< xDiv[i] <<" ";
1369 std::cout<<std::endl;
1370 //
1371}
1372
1373////////////////////////////////////////////////////////////////////////////////
1374/// User utility, miscellaneous and debug.
1375/// Checks all pointers in the tree of cells. This is useful auto diagnostic.
1376/// - level=0, no printout, failures causes STOP
1377/// - level=1, printout, failures lead to WARNINGS only
1378
1380{
1381 Int_t errors, warnings;
1382 TFoamCell *cell;
1383 Long_t iCell;
1384
1385 errors = 0; warnings = 0;
1386 if (level==1) std::cout << "///////////////////////////// FOAM_Checks /////////////////////////////////" << std::endl;
1387 for(iCell=1; iCell<=fLastCe; iCell++) {
1388 cell = fCells[iCell];
1389 // checking general rules
1390 if( ((cell->GetDau0()==0) && (cell->GetDau1()!=0) ) ||
1391 ((cell->GetDau1()==0) && (cell->GetDau0()!=0) ) ) {
1392 errors++;
1393 if (level==1) Error("CheckAll","ERROR: Cell's no %ld has only one daughter \n",iCell);
1394 }
1395 if( (cell->GetDau0()==0) && (cell->GetDau1()==0) && (cell->GetStat()==0) ) {
1396 errors++;
1397 if (level==1) Error("CheckAll","ERROR: Cell's no %ld has no daughter and is inactive \n",iCell);
1398 }
1399 if( (cell->GetDau0()!=0) && (cell->GetDau1()!=0) && (cell->GetStat()==1) ) {
1400 errors++;
1401 if (level==1) Error("CheckAll","ERROR: Cell's no %ld has two daughters and is active \n",iCell);
1402 }
1403
1404 // checking parents
1405 if( (cell->GetPare())!=fCells[0] ) { // not child of the root
1406 if ( (cell != cell->GetPare()->GetDau0()) && (cell != cell->GetPare()->GetDau1()) ) {
1407 errors++;
1408 if (level==1) Error("CheckAll","ERROR: Cell's no %ld parent not pointing to this cell\n ",iCell);
1409 }
1410 }
1411
1412 // checking daughters
1413 if(cell->GetDau0()!=0) {
1414 if(cell != (cell->GetDau0())->GetPare()) {
1415 errors++;
1416 if (level==1) Error("CheckAll","ERROR: Cell's no %ld daughter 0 not pointing to this cell \n",iCell);
1417 }
1418 }
1419 if(cell->GetDau1()!=0) {
1420 if(cell != (cell->GetDau1())->GetPare()) {
1421 errors++;
1422 if (level==1) Error("CheckAll","ERROR: Cell's no %ld daughter 1 not pointing to this cell \n",iCell);
1423 }
1424 }
1425 }// loop after cells;
1426
1427 // Check for empty cells
1428 for(iCell=0; iCell<=fLastCe; iCell++) {
1429 cell = fCells[iCell];
1430 if( (cell->GetStat()==1) && (cell->GetDriv()==0) ) {
1431 warnings++;
1432 if(level==1) Warning("CheckAll", "Warning: Cell no. %ld is active but empty \n", iCell);
1433 }
1434 }
1435 // summary
1436 if(level==1){
1437 Info("CheckAll","Check has found %d errors and %d warnings \n",errors, warnings);
1438 }
1439 if(errors>0){
1440 Info("CheckAll","Check - found total %d errors \n",errors);
1441 }
1442} // Check
1443
1444////////////////////////////////////////////////////////////////////////////////
1445/// Prints geometry of ALL cells of the FOAM
1446
1448{
1449 Long_t iCell;
1450
1451 for(iCell=0; iCell<=fLastCe; iCell++) {
1452 std::cout<<"Cell["<<iCell<<"]={ ";
1453 //std::cout<<" "<< fCells[iCell]<<" "; // extra DEBUG
1454 std::cout<<std::endl;
1455 fCells[iCell]->Print("1");
1456 std::cout<<"}"<<std::endl;
1457 }
1458}
1459
1460////////////////////////////////////////////////////////////////////////////////
1461/// Debugging tool which plots 2-dimensional cells as rectangles
1462/// in C++ format readable for root
1463
1465{
1466 std::ofstream outfile(filename, std::ios::out);
1467 Double_t x1,y1,x2,y2,x,y;
1468 Long_t iCell;
1469 Double_t offs =0.1;
1470 Double_t lpag =1-2*offs;
1471 outfile<<"{" << std::endl;
1472 outfile<<"cMap = new TCanvas(\"Map1\",\" Cell Map \",600,600);"<<std::endl;
1473 //
1474 outfile<<"TBox*a=new TBox();"<<std::endl;
1475 outfile<<"a->SetFillStyle(0);"<<std::endl; // big frame
1476 outfile<<"a->SetLineWidth(4);"<<std::endl;
1477 outfile<<"a->SetLineColor(2);"<<std::endl;
1478 outfile<<"a->DrawBox("<<offs<<","<<offs<<","<<(offs+lpag)<<","<<(offs+lpag)<<");"<<std::endl;
1479 //
1480 outfile<<"TText*t=new TText();"<<std::endl; // text for numbering
1481 outfile<<"t->SetTextColor(4);"<<std::endl;
1482 if(fLastCe<51)
1483 outfile<<"t->SetTextSize(0.025);"<<std::endl; // text for numbering
1484 else if(fLastCe<251)
1485 outfile<<"t->SetTextSize(0.015);"<<std::endl;
1486 else
1487 outfile<<"t->SetTextSize(0.008);"<<std::endl;
1488 //
1489 outfile<<"TBox*b=new TBox();"<<std::endl; // single cell
1490 outfile <<"b->SetFillStyle(0);"<<std::endl;
1491 //
1492 if(fDim==2 && fLastCe<=2000) {
1493 TFoamVect cellPosi(fDim); TFoamVect cellSize(fDim);
1494 outfile << "// =========== Rectangular cells ==========="<< std::endl;
1495 for(iCell=1; iCell<=fLastCe; iCell++) {
1496 if( fCells[iCell]->GetStat() == 1) {
1497 fCells[iCell]->GetHcub(cellPosi,cellSize);
1498 x1 = offs+lpag*( cellPosi[0]); y1 = offs+lpag*( cellPosi[1]);
1499 x2 = offs+lpag*(cellPosi[0]+cellSize[0]); y2 = offs+lpag*(cellPosi[1]+cellSize[1]);
1500 // cell rectangle
1501 if(fLastCe<=2000)
1502 outfile<<"b->DrawBox("<<x1<<","<<y1<<","<<x2<<","<<y2<<");"<<std::endl;
1503 // cell number
1504 if(fLastCe<=250) {
1505 x = offs+lpag*(cellPosi[0]+0.5*cellSize[0]); y = offs+lpag*(cellPosi[1]+0.5*cellSize[1]);
1506 outfile<<"t->DrawText("<<x<<","<<y<<","<<"\""<<iCell<<"\""<<");"<<std::endl;
1507 }
1508 }
1509 }
1510 outfile<<"// ============== End Rectangles ==========="<< std::endl;
1511 }//kDim=2
1512 //
1513 //
1514 outfile << "}" << std::endl;
1515 outfile.close();
1516}
1517
1519{
1520// Void function for backward compatibility
1521
1522 Info("LinkCells", "VOID function for backward compatibility \n");
1523 return;
1524}
1525
#define e(i)
Definition: RSha256.hxx:103
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:43
char Char_t
Definition: RtypesCore.h:31
const Bool_t kFALSE
Definition: RtypesCore.h:90
long Long_t
Definition: RtypesCore.h:52
double Double_t
Definition: RtypesCore.h:57
#define ClassImp(name)
Definition: Rtypes.h:361
#define BX1F(name, numb, text)
Definition: TFoam.cxx:102
#define BX1I(name, numb, text)
Definition: TFoam.cxx:100
#define BXCLO
Definition: TFoam.cxx:107
#define BXTXT(text)
Definition: TFoam.cxx:98
#define BX2F(name, numb, err, text)
Definition: TFoam.cxx:104
static const Double_t gVlow
Definition: TFoam.cxx:113
static const Double_t gHigh
Definition: TFoam.cxx:112
#define BXOPE
Definition: TFoam.cxx:95
float type_of_call hi(const int &, const int &)
double sqrt(double)
Used by TFoam.
Definition: TFoamCell.h:12
void SetXdiv(Double_t Xdiv)
Definition: TFoamCell.h:45
TFoamCell * GetDau1() const
Definition: TFoamCell.h:62
void CalcVolume()
Calculates volume of the cell using size params which are calculated.
Definition: TFoamCell.cxx:170
void Print(Option_t *option) const
Printout of the cell geometry parameters for the debug purpose.
Definition: TFoamCell.cxx:185
Double_t GetVolume() const
Definition: TFoamCell.h:50
Double_t GetDriv() const
Definition: TFoamCell.h:52
Int_t GetStat() const
Definition: TFoamCell.h:58
TFoamCell * GetDau0() const
Definition: TFoamCell.h:61
void SetStat(Int_t Stat)
Definition: TFoamCell.h:59
Double_t GetPrim() const
Definition: TFoamCell.h:53
Int_t GetBest() const
Definition: TFoamCell.h:43
void GetHcub(TFoamVect &, TFoamVect &) const
Provides size and position of the cell These parameter are calculated by analyzing information in all...
Definition: TFoamCell.cxx:116
TFoamCell * GetPare() const
Definition: TFoamCell.h:60
void SetSerial(Int_t Serial)
Definition: TFoamCell.h:65
Double_t GetIntg() const
Definition: TFoamCell.h:51
void Fill(Int_t, TFoamCell *, TFoamCell *, TFoamCell *)
Fills in certain data into newly allocated cell.
Definition: TFoamCell.cxx:103
void SetDau1(TFoamCell *Daug)
Definition: TFoamCell.h:64
void SetPrim(Double_t Prim)
Definition: TFoamCell.h:56
void SetDriv(Double_t Driv)
Definition: TFoamCell.h:55
void SetIntg(Double_t Intg)
Definition: TFoamCell.h:54
void SetDau0(TFoamCell *Daug)
Definition: TFoamCell.h:63
void SetBest(Int_t Best)
Definition: TFoamCell.h:44
Abstract class representing n-dimensional real positive integrand function.
Definition: TFoamIntegrand.h:9
virtual Double_t Density(Int_t ndim, Double_t *)=0
Small auxiliary class for controlling MC weight.
Definition: TFoamMaxwt.h:12
void Fill(Double_t)
Filling analyzed weight.
Definition: TFoamMaxwt.cxx:93
void GetMCeff(Double_t, Double_t &, Double_t &)
Calculates Efficiency= aveWt/wtLim for a given tolerance level epsilon<<1 using information stored in...
Definition: TFoamMaxwt.cxx:120
Auxiliary class TFoamVect of n-dimensional vector, with dynamic allocation used for the cartesian geo...
Definition: TFoamVect.h:10
TFoam is the main class of the multi-dimensional general purpose Monte Carlo event generator (integra...
Definition: TFoam.h:21
virtual void MakeActiveList()
Internal method used by Initialize.
Definition: TFoam.cxx:966
virtual void CheckAll(Int_t)
User utility, miscellaneous and debug.
Definition: TFoam.cxx:1379
TString fName
Name of a given instance of the FOAM class.
Definition: TFoam.h:24
Double_t fMCwt
MC weight.
Definition: TFoam.h:57
virtual Int_t Divide(TFoamCell *)
Internal method used by Initialize.
Definition: TFoam.cxx:933
virtual void PrintCells()
Prints geometry of ALL cells of the FOAM.
Definition: TFoam.cxx:1447
TH1D * fHistWt
Histogram of the MC wt.
Definition: TFoam.h:54
virtual void GetMCvect(Double_t *)
User may get generated MC point/vector with help of this method.
Definition: TFoam.cxx:1173
TFoamIntegrand * fRho
! Pointer to the user-defined integrand function/distribution
Definition: TFoam.h:60
TRandom * fPseRan
Pointer to user-defined generator of pseudorandom numbers.
Definition: TFoam.h:62
Double_t fMCerror
and its error
Definition: TFoam.h:72
Double_t fPrime
Primary integral R' (R=R'<wt>)
Definition: TFoam.h:70
Int_t fChat
Chat=0,1,2 chat level in output, Chat=1 normal level.
Definition: TFoam.h:32
virtual void InitCells()
Internal method used by Initialize.
Definition: TFoam.cxx:444
Double_t fNevGen
Total number of the generated MC events.
Definition: TFoam.h:68
virtual void MakeEvent()
User method.
Definition: TFoam.cxx:1123
Double_t fSumWt2
Total sum of wt and wt^2.
Definition: TFoam.h:66
Double_t fSumWt
Definition: TFoam.h:66
TFoamVect ** fXdivPRD
! Lists of division values encoded in one vector per direction
Definition: TFoam.h:42
virtual Long_t PeekMax()
Internal method used by Initialize.
Definition: TFoam.cxx:899
virtual void GenerCel2(TFoamCell *&)
Internal method.
Definition: TFoam.cxx:1085
virtual void Initialize()
Basic initialization of FOAM invoked by the user.
Definition: TFoam.cxx:320
virtual void GetIntNorm(Double_t &, Double_t &)
User method.
Definition: TFoam.cxx:1227
TFoamMaxwt * fMCMonit
Monitor of the MC weight for measuring MC efficiency.
Definition: TFoam.h:48
Int_t fRNmax
Maximum No. of the rand. numb. requested at once.
Definition: TFoam.h:29
Int_t * fInhiDiv
! [fDim] Flags for inhibiting cell division
Definition: TFoam.h:40
Long_t fNCalls
Total number of the function calls.
Definition: TFoam.h:64
virtual Double_t GetMCwt()
User may get weight MC weight using this method.
Definition: TFoam.cxx:1181
Double_t fWtMin
Maximum/Minimum MC weight.
Definition: TFoam.h:69
virtual void ResetRho(TFoamIntegrand *Rho)
User may optionally reset the distribution using this method.
Definition: TFoam.cxx:1050
Int_t fEvPerBin
Maximum number of effective (wt=1) events per bin.
Definition: TFoam.h:37
virtual void GetIntegMC(Double_t &, Double_t &)
User method.
Definition: TFoam.cxx:1208
Double_t fMaxWtRej
Maximum weight in rejection for getting wt=1 events.
Definition: TFoam.h:49
Int_t fNCells
Maximum number of cells.
Definition: TFoam.h:28
Double_t * fRvec
[fRNmax] random number vector from r.n. generator fDim+1 maximum elements
Definition: TFoam.h:58
virtual void RootPlot2dim(Char_t *)
Debugging tool which plots 2-dimensional cells as rectangles in C++ format readable for root.
Definition: TFoam.cxx:1464
Double_t * fAlpha
[fDim] Internal parameters of the hyper-rectangle
Definition: TFoam.h:74
Int_t fOptDrive
Optimization switch =1,2 for variance or maximum weight optimization.
Definition: TFoam.h:31
virtual void Explore(TFoamCell *Cell)
Internal method used by Initialize.
Definition: TFoam.cxx:519
virtual Double_t Eval(Double_t *)
Internal method.
Definition: TFoam.cxx:1063
virtual void MakeAlpha()
Internal method used by Initialize.
Definition: TFoam.cxx:846
virtual void ResetPseRan(TRandom *PseRan)
User may optionally reset random number generator using this method.
Definition: TFoam.cxx:1007
TMethodCall * fMethodCall
! ROOT's pointer to user-defined global distribution function
Definition: TFoam.h:61
Double_t Sqr(Double_t x) const
Definition: TFoam.h:140
Int_t fLastCe
Index of the last cell.
Definition: TFoam.h:45
Int_t fOptPRD
Option switch for predefined division, for quick check.
Definition: TFoam.h:41
TObjArray * fHistDbg
Histograms of wt, for debug.
Definition: TFoam.h:53
virtual void SetXdivPRD(Int_t, Int_t, Double_t[])
This should be called before Initialize, after setting kDim It predefines values of the cell division...
Definition: TFoam.cxx:1339
Double_t fSumOve
Total Sum of overweighted events.
Definition: TFoam.h:67
virtual void SetInhiDiv(Int_t, Int_t)
This can be called before Initialize, after setting kDim It defines which variables are excluded in t...
Definition: TFoam.cxx:1309
Double_t fWtMax
Definition: TFoam.h:69
std::vector< Long_t > fCellsAct
Index of active cells, constructed at the end of foam build-up.
Definition: TFoam.h:50
virtual ~TFoam()
Default destructor.
Definition: TFoam.cxx:227
Int_t * fMaskDiv
! [fDim] Dynamic Mask for cell division
Definition: TFoam.h:39
virtual void LinkCells(void)
Definition: TFoam.cxx:1518
virtual void SetRho(TFoamIntegrand *Rho)
User may use this method to set the distribution object.
Definition: TFoam.cxx:1019
virtual void SetRhoInt(Double_t(*fun)(Int_t, Double_t *))
User may use this method to set the distribution object as a global function pointer (and not as an i...
Definition: TFoam.cxx:1030
Int_t fNoAct
Number of active cells.
Definition: TFoam.h:44
virtual void Finalize(Double_t &, Double_t &)
May be called optionally by the user after the MC run.
Definition: TFoam.cxx:1257
Long_t fNEffev
Total number of effective events (wt=1) in the foam buildup.
Definition: TFoam.h:65
Int_t fOptRej
Switch =0 for weighted events; =1 for unweighted events in MC.
Definition: TFoam.h:33
Double_t * fPrimAcu
[fNoAct] Array of cumulative probability of all active cells
Definition: TFoam.h:51
virtual Double_t MCgenerate(Double_t *MCvect)
User method which generates MC event and returns MC weight.
Definition: TFoam.cxx:1196
Double_t * fMCvect
[fDim] Generated MC vector for the outside user
Definition: TFoam.h:56
TString fVersion
Actual version of the FOAM like (1.01m)
Definition: TFoam.h:25
virtual Int_t CellFill(Int_t, TFoamCell *)
Internal method used by Initialize.
Definition: TFoam.cxx:476
Int_t fDim
Dimension of the integration/simulation space.
Definition: TFoam.h:27
Int_t fNSampl
No. of MC events, when dividing (exploring) cell.
Definition: TFoam.h:36
TString fDate
Release date of FOAM.
Definition: TFoam.h:26
TFoamCell ** fCells
[fNCells] Array of ALL cells
Definition: TFoam.h:46
virtual void SetPseRan(TRandom *PseRan)
Definition: TFoam.h:112
TObjArray * fHistEdg
Histograms of wt, one for each cell edge.
Definition: TFoam.h:52
Double_t fMCresult
True Integral R from MC series.
Definition: TFoam.h:71
virtual void GetWtParams(Double_t, Double_t &, Double_t &, Double_t &)
May be called optionally after the MC run.
Definition: TFoam.cxx:1244
Int_t fNBin
No. of bins in the edge histogram for cell MC exploration.
Definition: TFoam.h:35
virtual void Grow()
Internal method used by Initialize.
Definition: TFoam.cxx:861
TFoam()
Default constructor for streamer, user should not use it.
Definition: TFoam.cxx:143
virtual void Varedu(Double_t[], Int_t &, Double_t &, Double_t &)
Internal method used by Initialize.
Definition: TFoam.cxx:671
virtual void Carver(Int_t &, Double_t &, Double_t &)
Internal method used by Initialize.
Definition: TFoam.cxx:748
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
virtual void Reset(Option_t *option="")
Reset.
Definition: TH1.cxx:9741
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1226
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:706
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:64
void SetParamPtrs(void *paramArr, Int_t nparam=-1)
ParamArr is an array containing the function argument values.
An array of TObjects.
Definition: TObjArray.h:37
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:356
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:865
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
virtual void RndmArray(Int_t n, Float_t *array)
Return an array of n random numbers uniformly distributed in ]0,1].
Definition: TRandom.cxx:577
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:541
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
const Double_t sigma
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
const char * Name
Definition: TXMLSetup.cxx:66
static long int sum(long int i)
Definition: Factory.cxx:2275