GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RandObj.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004 by Olivier Stezowski *
3  * stezow(AT)ipnl.in2p3.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
23 #ifndef ROOT_TRandom
24 #include <TRandom.h>
25 #endif
26 #ifndef ROOT_TH1D
27 #include <TH1D.h>
28 #endif
29 
30 #ifndef GW_RANDOM_H
31 #include "Random.h"
32 #endif
33 
34 #ifndef GW_RANDOBJ_H
35 #include "RandObj.h"
36 #endif
37 
38 #include <iostream>
39 
40 // namespace to be used
41 using namespace std;
42 using namespace Gw;
43 
45 
46 RandObj::RandObj() { fRand = Random::Instance(); fObj.SetOwner(kFALSE); }
47 RandObj::~RandObj() { fObj.Clear();}
48 
49 void RandObj::Add(TObject *obj, Float_t weight)
50 {
51  Int_t which;
52 
53  // check if obj already in the collection
54  which = fObj.IndexOf(obj);
55 
56  if (which == -1 ) { // new object
57  if ( weight < 0 )
58  {fObj.Add(obj); fWeight.push_back(-weight);}
59  else
60  {fObj.Add(obj); fWeight.push_back(weight); }
61  }
62  else { // obj already in the collection
63  if ( (fWeight[which] + weight) > 0 ) fWeight[which] = fWeight[which] + weight;
64  else {
65  fObj.Remove(obj); fObj.Compress(); fWeight.erase(fWeight.begin()+which);
66  }
67  }
68  ComputeCumu();
69 }
70 
71 void RandObj::ComputeCumu()
72 {
73  unsigned int i;
74 
75  fCumu.clear(); if ( fObj.GetEntries() == 0 ) return; // in case of empty collection
76 
77  // new size
78  fCumu.resize(fObj.GetEntries());
79 
80  // now compute the cumulative distribution
81  fCumu[0] = fWeight[0];
82  for( i = 1; i < fCumu.size(); i++ ){ fCumu[i] = fCumu[i-1] + fWeight[i]; }
83 
84  Double_t sum = fCumu[fCumu.size()-1];
85  for( i = 0; i < fCumu.size() ; i++ ){ if ( sum != 0.0 ) fCumu[i] = fCumu[i] / sum; }
86 }
87 
88 void RandObj::Clear(Option_t *options)
89 {
90  fObj.Clear(options); fWeight.clear(); fCumu.clear();
91 }
92 
93 TObject * RandObj::Rand()
94 {
95  Int_t sup, inf, middle; inf = 0; sup = fCumu.size();
96 
97  if ( sup == 1 ) return fObj[0];
98 
99  Double_t r = fRand->Current()->Rndm();
100 
101  while( (sup-inf) > 1) {
102  middle = (sup+inf)/2;
103  if (r == fCumu[middle-1]) return fObj[middle-1];
104  if (r < fCumu[middle-1])
105  sup = middle;
106  else
107  inf = middle;
108  }
109  return fObj[inf];
110 }
111 
112 
113 TObject * RandObj::Rand(Int_t &slot)
114 {
115  Int_t sup, inf, middle; inf = 0; sup = fCumu.size();
116 
117  if ( sup == 1 ) { slot = 0; return fObj[0]; }
118 
119  Double_t r = fRand->Current()->Rndm();
120 
121  while( (sup-inf) > 1) {
122  middle = (sup+inf)/2;
123  if (r == fCumu[middle-1]) { slot = middle-1; return fObj[middle-1]; }
124  if (r < fCumu[middle-1])
125  sup = middle;
126  else
127  inf = middle;
128  }
129  slot = inf; return fObj[slot];
130 }
131 
132 void RandObj::ls(Option_t* /*opt*/) const
133 {
134  cout << " # of objects " << fObj.GetEntries()
135  << " dim cumulative " << fCumu.size()
136  << " dim cumulative " << fWeight.size() << endl;
137 }
138 
139 void RandObj::FillRandom(TH1 *h, Int_t ntimes)
140 {
141  Int_t slot;
142 
143  if ( fObj.GetEntries() > 0 && ntimes > 0 ) {
144  h = new TH1D("RandObj","Random distribution from RandObj::FillRandom",fObj.GetEntries(),0,fObj.GetEntries());
145  for (Int_t i = 0; i < ntimes; i++ )
146  { RandObj::Rand(slot); h->Fill(slot); }
147  }
148  else h = NULL;
149 }
A class to select randomly an object in a TObjArray of objects.
Definition: RandObj.h:55
header file for a RandObj
header file for Random
ADF::LogMessage & endl(ADF::LogMessage &log)
ClassImp(RandObj)