Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NCUtility.cxx

Go to the documentation of this file.
00001 #include "NCUtility.h"
00002 
00003 #include "TH1.h"
00004 #include "TH2.h"
00005 #include "TH3.h"
00006 
00007 #include "TStopwatch.h"
00008 
00009 #include "MessageService/MsgService.h"
00010 
00011 #include <cassert>
00012 
00013 #include "sys/stat.h"
00014 
00015 CVSID("$Id: NCUtility.cxx,v 1.7 2010/01/20 15:41:32 rodriges Exp $");
00016 
00017 TH1* NC::Utility::CloneFast(const TH1* h)
00018 {
00019   const TString className = h->ClassName();
00020 
00021   if(className == "TH1F") return new TH1F(*((TH1F*)h));
00022   if(className == "TH1D") return new TH1D(*((TH1D*)h));
00023   if(className == "TH2F") return new TH2F(*((TH2F*)h));
00024   if(className == "TH2D") return new TH2D(*((TH2D*)h));
00025   if(className == "TH3F") return new TH3F(*((TH3F*)h));
00026   if(className == "TH3D") return new TH3D(*((TH3D*)h));
00027 
00028   MSG("NCUtility", Msg::kWarning) << "Histogram type "
00029                                   << className
00030                                   << " is not handled."
00031                                   << " Falling back to Clone()"
00032                                   << " which is slow." << endl;
00033   return (TH1*)h->Clone();
00034 }
00035 
00036 
00038 inline void GetArray(const TH1* h, float*& fArray, double*& dArray)
00039 {
00040   fArray = 0; dArray = 0;
00041 
00042   const TString className = h->ClassName();
00043 
00044   if(className == "TH1F") fArray = ((TH1F*)h)->fArray;
00045   if(className == "TH2F") fArray = ((TH2F*)h)->fArray;
00046   if(className == "TH3F") fArray = ((TH3F*)h)->fArray;
00047   if(className == "TH1D") dArray = ((TH1D*)h)->fArray;
00048   if(className == "TH2D") dArray = ((TH2D*)h)->fArray;
00049   if(className == "TH3D") dArray = ((TH3D*)h)->fArray;
00050 }
00051 
00052 
00053 int NC::Utility::GetArraySize(const TH1* h)
00054 {
00055   // Horrible hack to get at the number of entries in the underlying
00056   // representation of a TH1 subclass.
00057   struct CellsGetter: public TH1
00058   {
00059     int NCells()
00060     {
00061       return fNcells;
00062     }
00063   };
00064 
00065   return ((CellsGetter*)h)->NCells();
00066 }
00067 
00068 
00069 void NC::Utility::AddFast(TH1* a, const TH1* b, double c)
00070 {
00071   if(c == 0) return;
00072 
00073   assert(a->ClassName() == b->ClassName());
00074 
00075   const int N = GetArraySize(a);
00076   assert(GetArraySize(b) == N);
00077 
00078   float* fArrayA = 0;
00079   float* fArrayB = 0;
00080   double* dArrayA = 0;
00081   double* dArrayB = 0;
00082 
00083   GetArray(a, fArrayA, dArrayA);
00084   GetArray(b, fArrayB, dArrayB);
00085 
00086   if(!(fArrayA && fArrayB) && !(dArrayA && dArrayB)){
00087     MSG("NCUtility", Msg::kWarning) << "Histogram type "
00088                                     << a->ClassName()
00089                                     << " is not handled."
00090                                     << " Falling back to Add()"
00091                                     << " which is slow." << endl;
00092     a->Add(b, c);
00093     return;
00094   }
00095 
00096   if(fArrayA && fArrayB) for(int n = 0; n < N; ++n) fArrayA[n] += fArrayB[n]*c;
00097   if(dArrayA && dArrayB) for(int n = 0; n < N; ++n) dArrayA[n] += dArrayB[n]*c;
00098 }
00099 
00100 
00101 void NC::Utility::MultiplyFast(TH1* a, const TH1* b, double c)
00102 {
00103   assert(a->ClassName() == b->ClassName());
00104 
00105   const int N = GetArraySize(a);
00106   assert(GetArraySize(b) == N);
00107 
00108   float* fArrayA = 0;
00109   float* fArrayB = 0;
00110   double* dArrayA = 0;
00111   double* dArrayB = 0;
00112 
00113   GetArray(a, fArrayA, dArrayA);
00114   GetArray(b, fArrayB, dArrayB);
00115 
00116   if(!(fArrayA && fArrayB) && !(dArrayA && dArrayB)){
00117     MSG("NCUtility", Msg::kWarning) << "Histogram type "
00118                                     << a->ClassName()
00119                                     << " is not handled."
00120                                     << " Falling back to Multiply()"
00121                                     << " which is slow." << endl;
00122     a->Multiply(b);
00123     a->Scale(c);
00124     return;
00125   }
00126 
00127   if(fArrayA && fArrayB) for(int n = 0; n < N; ++n) fArrayA[n] *= fArrayB[n]*c;
00128   if(dArrayA && dArrayB) for(int n = 0; n < N; ++n) dArrayA[n] *= dArrayB[n]*c;
00129 }
00130 
00131 
00132 void NC::Utility::DivideFast(TH1* a, const TH1* b, double c)
00133 {
00134   assert(a->ClassName() == b->ClassName());
00135 
00136   const int N = GetArraySize(a);
00137   assert(GetArraySize(b) == N);
00138 
00139   float* fArrayA = 0;
00140   float* fArrayB = 0;
00141   double* dArrayA = 0;
00142   double* dArrayB = 0;
00143 
00144   GetArray(a, fArrayA, dArrayA);
00145   GetArray(b, fArrayB, dArrayB);
00146 
00147   if(!(fArrayA && fArrayB) && !(dArrayA && dArrayB)){
00148     MSG("NCUtility", Msg::kWarning) << "Histogram type "
00149                                     << a->ClassName()
00150                                     << " is not handled."
00151                                     << " Falling back to Divide()"
00152                                     << " which is slow." << endl;
00153     a->Divide(b);
00154     a->Scale(1/c);
00155     return;
00156   }
00157 
00158   if(fArrayA && fArrayB){
00159     for(int n = 0; n < N; ++n){
00160       const double denom = fArrayB[n]*c;
00161       if(denom) fArrayA[n] /= denom; else fArrayA[n] = 0;
00162     }
00163   }
00164 
00165   if(dArrayA && dArrayB){
00166     for(int n = 0; n < N; ++n){
00167       const double denom = dArrayB[n]*c;
00168       if(denom) dArrayA[n] /= denom; else dArrayA[n] = 0;
00169     }
00170   }
00171 }
00172 
00173 
00174 vector<TString> NC::Utility::ParseStringList(const char* sl)
00175 {
00176   TString strList = sl;
00177 
00178   vector<TString> ret;
00179 
00180   strList.Remove(TString::kBoth, ' '); // strip whitespace
00181 
00182   if(strList == "") return ret;
00183 
00184   int space = strList.First(' ');
00185 
00186   // If there aren't any spaces then we want 'head' to be the whole string
00187   if(space < 0) space = strList.Length();
00188 
00189   // Slicing operator takes start and length
00190   const TString head = strList(0, space);
00191   const TString tail = strList(space+1, strList.Length()-space);
00192 
00193   ret.push_back(head);
00194 
00195   // Recurse to parse the remainder of the string
00196   const vector<TString> rest = ParseStringList(tail);
00197   ret.insert(ret.end(), rest.begin(), rest.end());
00198 
00199   return ret;
00200 }
00201 
00202 
00203 vector<int> NC::Utility::ParseNumberList(const char* nl)
00204 {
00205   const vector<TString> sl = ParseStringList(nl);
00206 
00207   vector<int> ret;
00208 
00209   for(unsigned int n = 0; n < sl.size(); ++n){
00210     assert(sl[n].IsDigit());
00211     ret.push_back(sl[n].Atoi());
00212   }
00213 
00214   return ret;
00215 }
00216 
00217 
00218 void NC::Utility::ReportProgress(double est_frac, TStopwatch& sw)
00219 {
00220   // Check if we're outputing to a file. If so don't bother showing off
00221   // with the progress bar, it won't work.
00222   struct stat buf;
00223   fstat(fileno(stdout), &buf);
00224   const bool isFile = (buf.st_mode & S_IFREG) || (buf.st_mode & S_IFIFO);
00225 
00226   const double elapsed = sw.RealTime();
00227   sw.Start(kFALSE);
00228 
00229   if(est_frac < 0) est_frac = 0;
00230   if(est_frac > 1) est_frac = 1;
00231 
00232   const int remain = est_frac ? int(elapsed*(1/est_frac-1)) : 0;
00233 
00234   const TString txt = TString::
00235     Format("%d%% complete, approx %dh%dm%ds remain",
00236            int(100*est_frac), remain/3600, (remain/60)%60, remain%60);
00237 
00238   if(isFile){
00239     MSG("NCUtility", Msg::kInfo) << txt << std::endl;
00240   }
00241   else{
00242     TString bar;
00243     const int extra = 50-txt.Length();
00244     const int before = extra/2;
00245     const int after = extra-before;
00246 
00247     string plain_bar;
00248     for(int n = 0; n < before; ++n) plain_bar += " ";
00249     plain_bar += txt;
00250     for(int n = 0; n < after; ++n) plain_bar += " ";
00251 
00252     const char kColor_Reset[]   = { 0x1B, '[', '0', 'm', 0 };
00253     const char kColor_BgRed[]   = { 0x1B, '[', '4', '1', 'm', 0 };
00254     const char kColor_BgGreen[] = { 0x1B, '[', '4', '2', 'm', 0 };
00255 
00256     int fracInt = int(est_frac*50);
00257     if(fracInt < 0) fracInt = 0;
00258     if(fracInt > 50) fracInt = 50;
00259     bar += kColor_BgGreen;
00260     for(int n = 0; n < 50; ++n){
00261       if(n >= fracInt) bar += kColor_BgRed;
00262       bar += plain_bar[n];
00263     }
00264     bar += kColor_Reset;
00265 
00266     MSG("NCUtility", Msg::kInfo) << bar <<  "\r" << std::flush;
00267   }
00268 }

Generated on Mon Feb 15 11:07:04 2010 for loon by  doxygen 1.3.9.1