/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSHistogram.cc

00001 #include "BDSBin.hh"
00002 #include "BDSDebug.hh"
00003 #include "BDSHistogram.hh"
00004 
00005 #include <vector>
00006 #include <cfloat>
00007 #include <iostream>
00008 #include <string>
00009 #include <utility>
00010 #include "globals.hh"
00011 
00012 BDSHistogram1D::BDSHistogram1D(G4double xmin, G4double xmax, G4int nbins, G4String nameIn, G4String titleIn):
00013   name(nameIn),title(titleIn),entries(0)
00014 {
00015 #ifdef BDSDEBUG
00016   G4cout << __METHOD_NAME__ << "name: " << nameIn << ", title: " << titleIn << G4endl;
00017   G4cout << __METHOD_NAME__ << "xmin: " << xmin << ", xmax: " << xmax << ", nbins: " << nbins << G4endl;
00018 #endif
00019   // test to see we have at least 1 bin
00020   if (nbins < 1)
00021     {
00022       G4cerr << __METHOD_NAME__ << "must have at least 1 bin - nbins: " << nbins << G4endl;
00023       exit(1);
00024     }
00025   if (xmax <= xmin)
00026     {
00027       G4cerr << __METHOD_NAME__ << "xmax must be greater than xmin: xmax = "
00028              << xmax << ", xmin = " << xmin << G4endl;
00029       exit(1);
00030     }
00031   
00032   //underflow bin
00033   underflow = new BDSBin(DBL_MIN,xmin);
00034   
00035   // reserve size for speed optimisation
00036   bins.reserve(nbins);
00037 
00038   // calculate binwidth
00039   G4double binwidth = (xmax - xmin) / (G4double)nbins;
00040 #ifdef BDSDEBUG
00041   G4cout << __METHOD_NAME__ 
00042          << " S min : "      << xmin 
00043          << " m, S max : "   << xmax 
00044          << " m, nbins : " << nbins 
00045          << " Bin width: "  << binwidth 
00046          << " m" << G4endl;
00047 #endif
00048   G4double localmin, localmax;
00049   localmin = xmin;
00050   localmax = xmin + binwidth;
00051   BDSBin* tempbin = NULL;
00052   for (G4int i = 0; i < nbins; ++i)
00053     {
00054       tempbin = new BDSBin(localmin,localmax);
00055       bins.push_back(tempbin);
00056       localmin += binwidth;
00057       localmax += binwidth;
00058     }
00059   // overflow bin
00060   overflow = new BDSBin(xmax,DBL_MAX);
00061 
00062   //initialise iterators
00063   first();
00064 }
00065 
00066 BDSHistogram1D::BDSHistogram1D(std::vector<double> binEdges, G4String nameIn, G4String titleIn):
00067   name(nameIn),title(titleIn),entries(0)
00068 {
00069 #ifdef BDSDEBUG
00070   G4cout << __METHOD_NAME__ << "name: " << nameIn << ", title: " << titleIn << G4endl;
00071   G4cout << __METHOD_NAME__ << "xmin: " << binEdges.front() << ", xmax: " << binEdges.back() << ", nbins: " << binEdges.size() << G4endl;
00072 #endif
00073   // reserve size for speed optimisation
00074   bins.reserve(binEdges.size()-1); // -1 (for extra edge)
00075   
00076   // prepare iterators
00077   std::vector<double>::iterator iter, end;
00078   iter = binEdges.begin();
00079   end = binEdges.end();
00080   
00081   //underflow bin
00082   underflow = new BDSBin(DBL_MIN,*iter);
00083   
00084   BDSBin* tempbin    = NULL;
00085   G4double binstart  = 0;
00086   G4double binfinish = 0;
00087   if (binEdges.size() >= 2)
00088     {
00089       for (iter = binEdges.begin(); iter != (end-1); ++iter)
00090         {
00091           binstart  = *iter;
00092           binfinish = *(iter+1);
00093           if ((binfinish - binstart) > 1e-6)
00094             { //only add a bin if it's a finite width
00095               tempbin = new BDSBin(*iter,*(iter+1));
00096               bins.push_back(tempbin);
00097             }
00098         }
00099     }
00100   else if (binEdges.size() == 1)
00101     {
00102       // default 1x 1m bin
00103       tempbin = new BDSBin(binEdges.front(),binEdges.front()+1.0);
00104       bins.push_back(tempbin);
00105     }
00106   // else just underflow and overflow
00107   // overflow bin
00108   overflow = new BDSBin(binEdges.back(),DBL_MAX);
00109 
00110   //initialise iterators
00111   first();
00112 }
00113 
00114 G4String BDSHistogram1D::GetName() const
00115 { return name;}
00116 
00117 G4String BDSHistogram1D::GetTitle() const
00118 { return title;}
00119 
00120 void BDSHistogram1D::Empty()
00121 {
00122   for (std::vector<BDSBin*>::iterator i = bins.begin(); i != bins.end(); ++i)
00123     {(*i)->Empty();}
00124 }
00125 
00126 std::vector<BDSBin*> BDSHistogram1D::GetBins()const
00127 {
00128   return bins;
00129 }
00130 
00131 std::vector<G4double> BDSHistogram1D::GetBinValues()const
00132 {
00133   std::vector<G4double> result;
00134   if (bins.size() < 1)
00135     {return result;}
00136   for (std::vector<BDSBin*>::const_iterator i = bins.begin(); i != bins.end(); ++i)
00137     {result.push_back((*i)->GetValue());}
00138   return result;
00139 }
00140 
00141 std::vector<std::pair<G4double, G4double> > BDSHistogram1D::GetBinXMeansAndTotals()const
00142 {
00143   std::vector<std::pair<G4double ,G4double> > result;
00144   if (bins.size() < 1)
00145     {return result;}
00146   for (std::vector<BDSBin*>::const_iterator i = bins.begin(); i != bins.end(); ++i)
00147     {result.push_back( (*i)->GetXMeanAndTotal() );}
00148   return result;
00149 }
00150 
00151 std::vector<G4double> BDSHistogram1D::GetBinLowerEdges() const
00152 {
00153   std::vector<G4double> result;
00154   if (bins.size() < 1)
00155     {return result;}
00156   for (std::vector<BDSBin*>::const_iterator i = bins.begin(); i != bins.end(); ++i)
00157     {result.push_back( (*i)->GetLowerEdge() );}
00158   return result;
00159 }
00160 
00161 void BDSHistogram1D::PrintBins()const
00162 {
00163   G4cout << G4endl;
00164   G4cout << "Name: " << name << G4endl;
00165   G4cout << "Underflow: " << *underflow << G4endl;
00166   G4cout << "Overflow:  " << *overflow  << G4endl;
00167   for (std::vector<BDSBin*>::const_iterator i = bins.begin(); i != bins.end(); ++i)
00168     {G4cout << **i << G4endl;}
00169 }
00170 
00171 std::pair<BDSBin*, BDSBin*> BDSHistogram1D::GetUnderOverFlowBins() const
00172 {
00173   return std::make_pair(underflow,overflow);
00174 }
00175 
00176 std::pair<G4double,G4double> BDSHistogram1D::GetUnderOverFlowBinValues()const
00177 {
00178   return std::make_pair(bins.front()->GetValue(),bins.back()->GetValue());
00179 }
00180 
00181 BDSBin* BDSHistogram1D::GetUnderflowBin() const
00182 {return underflow;}
00183 
00184 BDSBin* BDSHistogram1D::GetOverflowBin() const
00185 {return overflow;}
00186 
00187 BDSBin* BDSHistogram1D::GetFirstBin() const
00188 {return bins.front();}
00189 
00190 BDSBin* BDSHistogram1D::GetLastBin() const
00191 {return bins.back();}
00192 
00193 size_t BDSHistogram1D::GetNBins() const
00194 {return bins.size();}
00195 
00196 G4int BDSHistogram1D::GetNEntries() const
00197 {return entries;}
00198 
00199 void BDSHistogram1D::Fill(G4double x)
00200 {
00201   Fill(x,1.0); // fill with weigth = 1
00202   entries++;
00203 }
00204 
00205 void BDSHistogram1D::Fill(G4double x, G4double weight)
00206 {
00207   //iterate through vector and check if x in bin range
00208   if (underflow->InRange(x))
00209     {(*underflow)+=1; return;}
00210   if (overflow->InRange(x))
00211     {(*overflow)+=1; return;}
00212   for (std::vector<BDSBin*>::iterator i = bins.begin(); i != bins.end(); ++i)
00213     {
00214       if ((*i)->InRange(x))
00215         { (*(*i)) += weight; break;}
00216     }
00217   entries++;
00218 }
00219 
00220 BDSHistogram1D::~BDSHistogram1D()
00221 {
00222   //must clear the bins from the heap
00223 #ifdef BDSDEBUG
00224   G4cout << "BDSHistorgram1D > emptying bins" << G4endl;
00225 #endif
00226   for (std::vector<BDSBin*>::iterator i = bins.begin(); i != bins.end(); ++i)
00227     {delete *i;}
00228   delete underflow;
00229   delete overflow;
00230 }
00231 
00232 std::ostream& operator<< (std::ostream &out, BDSHistogram1D const &hist)
00233 {
00234   return out << "### FirstBinLeft = " << hist.GetFirstBin()->GetLowerEdge() 
00235              << " LastBinLeft = " << hist.GetLastBin()->GetLowerEdge()
00236              << " NBins = " << hist.GetBins().size();
00237 }
00238 
00239 BDSBin* BDSHistogram1D::currentBin()
00240 {
00241   return *_iterBins;
00242 }
00243 
00244 void BDSHistogram1D::first()
00245 {
00246   _iterBins = bins.begin();
00247 }
00248 
00249 G4bool BDSHistogram1D::isLastBin()
00250 {
00251   // size safe evalutation of whether we're at the last item
00252   // can be done with std::next but prefer not to use c++11
00253   return ((_iterBins != bins.end()) && (_iterBins + 1 == bins.end()));
00254 }
00255 
00256 G4bool BDSHistogram1D::isDone()
00257 {
00258   return (_iterBins == bins.end());
00259 }
00260 
00261 void BDSHistogram1D::next()
00262 {
00263   _iterBins++;
00264 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7