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

NuMatrixSpectrum.cxx

Go to the documentation of this file.
00001 #include <cassert>
00002 #include <stdexcept>
00003 #include <fstream>
00004 #include <sstream>
00005 
00006 #include "TCanvas.h"
00007 #include "TPad.h"
00008 #include "TGaxis.h"
00009 #include "TPave.h"
00010 #include "TF1.h"
00011 
00012 #include "TFile.h"
00013 #include "TGraph.h"
00014 #include "TH1D.h"
00015 #include "TH2D.h"
00016 #include "TMath.h"
00017 #include "TLatex.h"
00018 #include "TGraphAsymmErrors.h"
00019 
00020 #include "Conventions/Munits.h"
00021 #include "MessageService/MsgService.h"
00022 #include "NtupleUtils/NuMatrixSpectrum.h"
00023 #include "NtupleUtils/NuUtilities.h"
00024 #include "NtupleUtils/NuFluctuator.h"
00025 
00026 ClassImp(NuMatrixSpectrum)
00027 
00028 CVSID("$Id: NuMatrixSpectrum.cxx,v 1.54 2010/02/05 12:32:48 bckhouse Exp $");
00029 
00030 double NuMatrixSpectrum::compress = 2.5;
00031 
00032 //____________________________________________________________________72
00033 NuMatrixSpectrum::NuMatrixSpectrum() 
00034 : PoiUp(200), PoiDn(200), DoPoisson(false)
00035 {
00036   this->fSpectrum = 0;
00037   this->fPoT = 0.0;
00038 }
00039 
00040 //____________________________________________________________________72
00041 NuMatrixSpectrum::NuMatrixSpectrum(const TH1D& spectrum)
00042 : PoiUp(200), PoiDn(200), DoPoisson(false)
00043 {
00044   this->fSpectrum = new TH1D(spectrum);
00045   fSpectrum->SetDirectory(0);
00046   this->fPoT = 0.0;
00047 }
00048 
00049 //____________________________________________________________________72
00050 NuMatrixSpectrum::NuMatrixSpectrum(const TH1D& spectrum,
00051                                    const Double_t pot) 
00052 : PoiUp(200), PoiDn(200), DoPoisson(false)
00053 {
00054   this->fSpectrum = new TH1D(spectrum);
00055   fSpectrum->SetDirectory(0);
00056   this->fPoT = pot;
00057 }
00058 
00059 //____________________________________________________________________72
00060 
00061 NuMatrixSpectrum::NuMatrixSpectrum( const string& filename,
00062                                     const string& histname,
00063                                     const string & POTHistname)
00064 : PoiUp(200), PoiDn(200), DoPoisson(false)
00065 {
00066   // Reset these - if this function fails, we don't want the user to
00067   // think that it passed.
00068   this->fSpectrum = 0;
00069   this->fPoT = 0.0;
00070   
00071   // Open the file
00072   TFile specfile(filename.c_str(), "READ");
00073   if (!specfile.IsOpen()) {
00074     ostringstream msg;
00075     msg << "Failed to open file " << filename;
00076     MSG("NuMatrixSpectrum",Msg::kError) << msg.str() << endl;
00077     throw runtime_error(msg.str().c_str());
00078   }
00079   
00080   // Grab the spectrum and POT histogram
00081   TH1D *spec = (TH1D*)specfile.Get(histname.c_str());
00082   TH1F *pot = (TH1F*)specfile.Get(POTHistname.c_str());
00083 
00084   // Check we actually got these, and fail if we didn't.
00085   if (!spec) {
00086     MSG("NuMatrixSpectrum",Msg::kError)
00087       << "Cannot read histogram " << histname << " from file "
00088       << filename << endl;
00089     return;
00090   }
00091   if (pot) {
00092     this->fPoT = pot->Integral();
00093   } else {
00094     MSG("NuMatrixSpectrum",Msg::kWarning)
00095       << "Cannot read POT histogram " << POTHistname << " from file "
00096       << filename << ". Defaulting to 0 POT" << endl;
00097     this->fPoT = 0;
00098   }
00099   
00100   // Now update the internal values
00101   this->fSpectrum = new TH1D(*spec);
00102   this->fSpectrum->SetDirectory(0);
00103 }
00104 
00105 
00106 //____________________________________________________________________72
00107 
00108 NuMatrixSpectrum::NuMatrixSpectrum(TFile *specfile,
00109                                    const string& histname,
00110                                    const string & POTHistname)
00111 : PoiUp(200), PoiDn(200), DoPoisson(false)
00112 {
00113   // Reset these - if this function fails, we don't want the user to
00114   // think that it passed.
00115   this->fSpectrum = 0;
00116   this->fPoT = 0.0;
00117   
00118   // Grab the spectrum and POT histogram
00119   TH1D *spec = (TH1D*)specfile->Get(histname.c_str());
00120   TH1F *pot = (TH1F*)specfile->Get(POTHistname.c_str());
00121   
00122   // Check we actually got these, and fail if we didn't.
00123   if (!spec) {
00124     MSG("NuMatrixSpectrum",Msg::kError)
00125     << "Cannot read histogram " << histname << " from file "
00126     << specfile->GetName() << endl;
00127     return;
00128   }
00129   if (pot) {
00130     this->fPoT = pot->Integral();
00131   } else {
00132     MSG("NuMatrixSpectrum",Msg::kWarning)
00133     << "Cannot read histogram " << POTHistname << " from file "
00134     << specfile->GetName() << endl;
00135     this->fPoT = 0;
00136   }
00137   
00138   // Now update the internal values
00139   this->fSpectrum = new TH1D(*spec);
00140   this->fSpectrum->SetDirectory(0);
00141 }
00142                   
00143 //____________________________________________________________________72
00144 NuMatrixSpectrum::NuMatrixSpectrum(const Double_t pot)
00145 : PoiUp(200), PoiDn(200), DoPoisson(false)
00146 {
00147   this->fSpectrum = 0; //new TH1D(spectrum);
00148   this->fPoT = pot;
00149 }
00150 //____________________________________________________________________72
00151 NuMatrixSpectrum::NuMatrixSpectrum(const NuMatrixSpectrum& original)
00152 : PoiUp(200), PoiDn(200), DoPoisson(false)
00153 {
00154   // Don't copy if the original has no spectrum
00155   if (original.fSpectrum) {
00156     this->fSpectrum = new TH1D(*(original.fSpectrum));
00157     fSpectrum->SetDirectory(0);
00158   } else {
00159     this->fSpectrum = 0;
00160   }
00161   this->fPoT = original.fPoT;
00162 }
00163 
00164 //____________________________________________________________________72
00165 NuMatrixSpectrum::~NuMatrixSpectrum()
00166 {
00167   if (fSpectrum){delete fSpectrum; fSpectrum = 0;}
00168 }
00169 
00170 //____________________________________________________________________72
00171 NuMatrixSpectrum& NuMatrixSpectrum
00172 ::operator = (const NuMatrixSpectrum& original)
00173 {
00174   if(this == &original) return *this;
00175 
00176   if(fSpectrum) delete fSpectrum;
00177 
00178   if(original.fSpectrum){
00179     fSpectrum =  new TH1D(*(original.fSpectrum));
00180     fSpectrum->SetDirectory(0);
00181   }
00182   else{
00183     fSpectrum = 0;
00184   }
00185   fPoT = original.fPoT;
00186 
00187   return *this;
00188 }
00189 
00190 //____________________________________________________________________72
00191 const char * NuMatrixSpectrum::GetName() const
00192 {
00193   if (fSpectrum) return fSpectrum->GetName();
00194   return "Blank";
00195 }
00196 
00197 //____________________________________________________________________72
00198 void NuMatrixSpectrum::SetName(const char * _name)
00199 {
00200   if (fSpectrum) fSpectrum->SetName(_name);
00201   else MSG("NuMatrixSpectrum", Msg::kWarning) << "Failed to set name to " << _name 
00202     << ".  There is not yet a spectrum in this NuMatrixSpectrum." << endl;
00203 }
00204 
00205 //____________________________________________________________________72
00206 void NuMatrixSpectrum::ResetSpectrum(TH1D& spectrum)
00207 {
00208   if (fSpectrum) delete fSpectrum;
00209   fSpectrum = new TH1D(spectrum);
00210 }
00211 
00212 //____________________________________________________________________72
00213 void NuMatrixSpectrum::Multiply(const TH1D* correction)
00214 {
00215   fSpectrum->Multiply(correction);
00216   /* Not Correct
00217   if (DoPoisson) {
00218     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson, assuming correction " 
00219     << correction->GetName() << " has 0 error." << endl;
00220     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00221       PoiUp[i] *= correction->GetBinContent(i+1);
00222       PoiDn[i] *= correction->GetBinContent(i+1);
00223     }
00224   } 
00225   */
00226 }
00227 
00228 //____________________________________________________________________72
00229 void NuMatrixSpectrum::Multiply(TF1* correction)
00230 {
00231   fSpectrum->Multiply(correction);
00232   /* Not Correct
00233   if (DoPoisson) {
00234     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson, assuming correction " 
00235     << correction->GetName() << " has 0 error." << endl;
00236     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00237       PoiUp[i] *= correction->Eval(fSpectrum->GetBinCenter(i+1));
00238       PoiDn[i] *= correction->Eval(fSpectrum->GetBinCenter(i+1));
00239     }
00240   } 
00241   */
00242 }
00243 
00244 //____________________________________________________________________72
00245 void NuMatrixSpectrum::Multiply(const TGraph* correction)
00246 {
00247   for(int i=1; i<=fSpectrum->GetNbinsX(); i++) {
00248     fSpectrum->SetBinContent(i,fSpectrum->GetBinContent(i) *
00249                              correction->Eval(fSpectrum->
00250                                               GetBinCenter(i),0,""));
00251     fSpectrum->SetBinError(i,fSpectrum->GetBinError(i) *
00252                            correction->Eval(fSpectrum->
00253                                             GetBinCenter(i),0,""));
00254   }
00255   /* Not Correct
00256   if (DoPoisson) {
00257     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson, assuming correction " 
00258     << correction->GetName() << " has 0 error." << endl;
00259     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00260       PoiUp[i] *= correction->Eval(fSpectrum->GetBinCenter(i+1),0,"");
00261       PoiDn[i] *= correction->Eval(fSpectrum->GetBinCenter(i+1),0,"");
00262     }
00263   }      
00264   */
00265 }
00266 
00267 //____________________________________________________________________72
00268 void NuMatrixSpectrum::Multiply(const Double_t scaleFactor)
00269 {
00270   fSpectrum->Scale(scaleFactor);
00271   /* Not Correct
00272   if (DoPoisson) {
00273     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson errors by " << scaleFactor << endl;
00274     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00275       PoiUp[i] *= scaleFactor;
00276       PoiDn[i] *= scaleFactor;
00277     }
00278   }
00279   */
00280 }
00281 
00282 
00283 //____________________________________________________________________72
00284 void NuMatrixSpectrum::Divide(const TH1D* correction, Option_t* option)
00285 {
00286   fSpectrum->Divide(fSpectrum, correction, 1, 1, option);
00287   /* Not Correct
00288   if (DoPoisson) {
00289     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson, assuming correction " 
00290     << correction->GetName() << " has 0 error." << endl;
00291     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00292       PoiUp[i] /= correction->GetBinContent(i+1);
00293       PoiDn[i] /= correction->GetBinContent(i+1);
00294     }
00295   }
00296   */
00297 }
00298 
00299 //____________________________________________________________________72
00300 void NuMatrixSpectrum::Divide(const TGraph* correction)
00301 {
00302   for(int i=1; i<=fSpectrum->GetNbinsX(); i++) {
00303     fSpectrum->SetBinContent(i,fSpectrum->GetBinContent(i) /
00304                              correction->Eval(fSpectrum->
00305                                               GetBinCenter(i),0,""));
00306     fSpectrum->SetBinError(i,fSpectrum->GetBinError(i) /
00307                            correction->Eval(fSpectrum->
00308                                             GetBinCenter(i),0,""));
00309   }
00310   /* Not Correct
00311   if (DoPoisson) {
00312     MSG("NuMatrixSpectrum",Msg::kInfo) << "Scaling Poisson, assuming correction " 
00313     << correction->GetName() << " has 0 error." << endl;
00314     for (int i = 0; i < fSpectrum->GetNbinsX(); i++) {
00315       PoiUp[i] /= correction->Eval(fSpectrum->GetBinCenter(i+1),0,"");
00316       PoiDn[i] /= correction->Eval(fSpectrum->GetBinCenter(i+1),0,"");
00317     }
00318   }        
00319   */
00320 }
00321 
00322 //____________________________________________________________________72
00323 void NuMatrixSpectrum::Divide(const Double_t scaleFactor)
00324 {
00325   Double_t lowCheck = 1.0e-5;
00326   if (scaleFactor>lowCheck){
00327     Multiply(1.0/scaleFactor);
00328   }
00329   else{
00330     MSG("NuMatrixSpectrum",Msg::kWarning)
00331     << "Trying to divide by a number < " << lowCheck << endl;
00332     assert(false);
00333   }
00334 }
00335 
00336 
00337 //____________________________________________________________________72
00338 void NuMatrixSpectrum::MultiplyPurity(const TH1D* correction,
00339                                       const Double_t correctionShift)
00340 {
00341   TH1D oneMinusCorrection(*correction);
00342   oneMinusCorrection.Reset();
00343   for (Int_t bin=0; bin<=oneMinusCorrection.GetNbinsX()+1; ++bin){
00344     oneMinusCorrection.SetBinContent(bin,1.0);
00345   }
00346   oneMinusCorrection.Add(correction,-1.0);
00347   TH1D background(*fSpectrum);
00348   background.Multiply(&oneMinusCorrection);
00349   background.Scale(correctionShift);
00350 
00351   fSpectrum->Add(&background,-1.0);
00352   
00353   if (DoPoisson) {
00354     DoPoisson = false;
00355     MSG("NuMatrixSpectrum",Msg::kWarning) << "Poisson errors cannot handle purity corrections.  Ignoring Poisson errors." << endl;
00356   }
00357 }
00358 
00359 //____________________________________________________________________72
00360 void NuMatrixSpectrum::DividePurity(const TH1D* correction,
00361                                     const Double_t correctionShift)
00362 {
00363   TH1D oneOverCorrMinusOne(*correction);
00364   oneOverCorrMinusOne.Reset();
00365   for (Int_t bin=0; bin<=oneOverCorrMinusOne.GetNbinsX()+1; ++bin){
00366     oneOverCorrMinusOne.SetBinContent(bin,1.0);
00367   }
00368   oneOverCorrMinusOne.Divide(correction);
00369   for (Int_t bin=0; bin<=oneOverCorrMinusOne.GetNbinsX()+1; ++bin){
00370     oneOverCorrMinusOne.
00371       SetBinContent(bin,
00372                     oneOverCorrMinusOne.GetBinContent(1)-1.0);
00373   }
00374 
00375 
00376 
00377   TH1D background(*fSpectrum);
00378   background.Multiply(&oneOverCorrMinusOne);
00379   background.Scale(correctionShift);
00380 
00381   fSpectrum->Add(&background);
00382 
00383   if (DoPoisson) {
00384     DoPoisson = false;
00385     MSG("NuMatrixSpectrum",Msg::kWarning) << "Poisson errors cannot handle purity corrections.  Ignoring Poisson errors." << endl;
00386   }
00387 }
00388 
00389 //____________________________________________________________________72
00390 void NuMatrixSpectrum::RecoToTrue(const TH2D* correction)
00391 {
00392   this->YToX(correction);
00393 }
00394 
00395 //____________________________________________________________________72
00396 void NuMatrixSpectrum::TrueToReco(const TH2D* correction)
00397 {
00398   this->XToY(correction);
00399 }
00400 
00401 //____________________________________________________________________72
00402 void NuMatrixSpectrum::GenerateSystErrors() 
00403 {
00404   double ebins[] = {0,     4,     8,     12,    16,    20,    30,    50, 200};
00405   double errbins[]    = {0.078, 0.070, 0.055, 0.060, 0.065, 0.092, 0.10,  1.0};
00406   double c, energy, err1, err2, errtot;
00407   for (int i = 1; i <= fSpectrum->GetNbinsX(); i++) {
00408     energy = fSpectrum->GetBinLowEdge(i);
00409     c = fSpectrum->GetBinContent(i);
00410     err1 = fSpectrum->GetBinError(i);
00411     
00412     for (int j = 0; j < 8; j++) {
00413       if (energy >= ebins[j] && energy < ebins[j+1]) {
00414         err2 = c*errbins[j];
00415         errtot = sqrt(err1*err1+err2*err2);
00416         fSpectrum->SetBinError(i, errtot);
00417       }
00418     }
00419   }   
00420 }
00421 
00422 //____________________________________________________________________72
00423 void NuMatrixSpectrum::GenerateErrors(Double_t scale)
00424 {
00425   Multiply(scale);
00426   double c, err1, err2, errtot;
00427   for (int i = 1; i <= fSpectrum->GetNbinsX(); i++) {
00428     c = fSpectrum->GetBinContent(i);
00429     err1 = fSpectrum->GetBinError(i);
00430     err2 = sqrt(c);
00431     errtot = sqrt(err1*err1+err2*err2);
00432     fSpectrum->SetBinError(i, errtot);
00433   }     
00434   Divide(scale);
00435 }
00436 
00437 //____________________________________________________________________72
00438 void NuMatrixSpectrum::RemoveErrors()
00439 {
00440   for (int i = 0; i <= fSpectrum->GetNbinsX() + 1; i++) {
00441     fSpectrum->SetBinError(i, 0);
00442   }  
00443 }
00444 
00445 //____________________________________________________________________72
00446 void NuMatrixSpectrum::BinWidthNormalize()
00447 {
00448   double w0, wi, w, c, e;
00449   w0 = fSpectrum->GetBinWidth(1);
00450   
00451   for (int i = 0; i <= fSpectrum->GetNbinsX() + 1; i++) {
00452     wi = fSpectrum->GetBinWidth(i);
00453     w = wi/w0;
00454     c = fSpectrum->GetBinContent(i);
00455     e = fSpectrum->GetBinError(i);
00456     fSpectrum->SetBinContent(i, c/w);
00457     fSpectrum->SetBinError(i, e/w);
00458       
00459     // Make sure to also scale the poisson errors we have calculated
00460     if (DoPoisson && i >= 1 && i <= fSpectrum->GetNbinsX()) {
00461       PoiUp[i-1] /= w;
00462       PoiDn[i-1] /= w;
00463     }
00464   }  
00465 }
00466 
00467 
00468 //____________________________________________________________________72
00469 void NuMatrixSpectrum::NuBarCompressX()
00470 {
00471   //cout << "Calling NuBarCompressX:" << endl
00472   //<< "  Make sure this step is performed after you have rebinned into" << endl
00473   //<< "  your desired binning scheme AND have already called BinWidthNormalize" << endl
00474   //<< "  since this method changes the width of the bins." << endl;
00475   
00476   // Get Current Bins
00477   Double_t bins_old[99];
00478   Double_t bins_new[99];
00479   GetXaxis()->GetLowEdge(bins_old);
00480   int Nbins = GetXaxis()->GetNbins();
00481   //cout << "Nbins = " << Nbins << endl;
00482   // Compress bins - number of bins stays the same
00483   //   but higher bins become half as wide
00484   for (int i = 0; i <= Nbins; i++) {
00485     if (i == Nbins) { // Overflow bin special case
00486       bins_new[i] = bins_new[i-1] + 150./compress; 
00487     }
00488     else if (bins_old[i] < 20.001) {
00489       bins_new[i] = bins_old[i];
00490     }
00491     else {
00492       double width = bins_old[i] - bins_old[i-1];
00493       bins_new[i] = bins_new[i-1] + width/compress;
00494     }
00495   }
00496   
00497   // Reassign bin contents based on bin number, 
00498   // not on actual bin value.
00499   TH1D newHist("NewHist", "", Nbins, bins_new);
00500   for (int i = 1; i < Nbins+1; i++) {
00501     newHist.SetBinContent(i, fSpectrum->GetBinContent(i));
00502     newHist.SetBinError(i, fSpectrum->GetBinError(i));
00503   }
00504   
00505   // Store our new hist as fSpectrum
00506   string name = fSpectrum->GetName();
00507   string title = fSpectrum->GetTitle();
00508   ResetSpectrum(newHist);
00509   fSpectrum->SetName(name.c_str());
00510   fSpectrum->SetTitle(name.c_str());
00511   
00512   // Style away the axis and labels since they are meaningless
00513   // fSpectrum->SetAxisColor(kWhite); // White ticks interfere with plot
00514   fSpectrum->GetXaxis()->SetTickLength(0);
00515   fSpectrum->SetLabelSize(0);
00516   SetRangeUser(0, bins_new[Nbins-1] - 0.005);
00517 }
00518 
00519 
00520 //____________________________________________________________________72
00521 void NuMatrixSpectrum::CompressTopBins()
00522 {
00523   //cout << "Calling NuBarCompressX:" << endl
00524   //<< "  Make sure this step is performed after you have rebinned into" << endl
00525   //<< "  your desired binning scheme AND have already called BinWidthNormalize" << endl
00526   //<< "  since this method changes the width of the bins." << endl;
00527   
00528   // Get Current Bins
00529   Double_t bins_old[99];
00530   Double_t bins_new[99];
00531   GetXaxis()->GetLowEdge(bins_old);
00532   int Nbins = GetXaxis()->GetNbins();
00533   //cout << "Nbins = " << Nbins << endl;
00534   // Compress bins - number of bins stays the same
00535   //   but higher bins become half as wide
00536   for (int i = 0; i <= Nbins-3; i++) {
00537     bins_new[i] = bins_old[i];
00538   }
00539   double base = bins_new[Nbins-3];
00540   bins_new[Nbins-2] = base+2;
00541   bins_new[Nbins-1] = base+4;
00542   bins_new[Nbins]   = base+6;
00543   
00544   
00545   // Reassign bin contents based on bin number, 
00546   // not on actual bin value.
00547   TH1D newHist("NewHist", "", Nbins, bins_new);
00548   for (int i = 1; i < Nbins+1; i++) {
00549     newHist.SetBinContent(i, fSpectrum->GetBinContent(i));
00550     newHist.SetBinError(i, fSpectrum->GetBinError(i));
00551   }
00552   
00553   // Store our new hist as fSpectrum
00554   string name = fSpectrum->GetName();
00555   string title = fSpectrum->GetTitle();
00556   ResetSpectrum(newHist);
00557   fSpectrum->SetName(name.c_str());
00558   fSpectrum->SetTitle(name.c_str());
00559 }
00560 
00561 //____________________________________________________________________72
00562 TF1* NuMatrixSpectrum::GetAxisFunc()
00563 {
00564     TString form = "(x<=20)*x+(x > 20)*(20+(x-20)/";
00565     form += compress;
00566     form += ")";
00567     TF1 * fAxis = new TF1("fAxis",form.Data(),0,50);    
00568     return fAxis;
00569 }
00570 
00571 //____________________________________________________________________72
00572 void NuMatrixSpectrum::DrawNuBarAxes(int lsize) 
00573 {
00574   gPad->Update();
00575   
00576   double aspectRatio = (double)gPad->GetCanvas()->GetWindowWidth() / (double)gPad->GetCanvas()->GetWindowHeight();
00577   cout << "Found aspectRatio = " << gPad->GetCanvas()->GetWindowWidth() << " / " << gPad->GetCanvas()->GetWindowHeight();
00578   bool wide = aspectRatio > 7./5. - 0.002;
00579   //bool wide = false;
00580   if (wide) cout << " (wide)" << endl;
00581   else cout << " (narrow)" << endl;
00582 
00583   double xmax = gPad->GetUxmax();
00584   double ymin = gPad->GetUymin();
00585   double ymax = gPad->GetUymax();
00586   if (gPad->GetLogy()) {
00587     ymin = pow(10, ymin);
00588     ymax = pow(10, ymax);
00589   }
00590   
00591   MAXMSG("NuMatrixSpectrum",Msg::kInfo,3) << "Drawing compressed axis from 0 to " 
00592   << xmax << " at y = " << ymin << " and y = " << ymax << endl;
00593   
00594   //cout << "compress = " << form << endl;
00595   TF1 * fAxis = GetAxisFunc();
00596   fAxis->GetName();  // Get rid of warning
00597     
00598   int div = 510;
00599   //if (wide) div = 510;
00600   //else div = 509;
00601   
00602   TGaxis *aBotFD = new TGaxis(0,ymin,xmax,ymin,"fAxis",div);
00603   aBotFD->SetLabelSize(0); // Drawing manually now
00604   aBotFD->Draw();
00605   
00606   TGaxis *aTopFD = new TGaxis(0,ymax,xmax,ymax,"fAxis",div,"-");
00607   aTopFD->SetLabelSize(0);
00608   aTopFD->Draw();
00609 
00610   // Draw the axis labels manually instead
00611   const char *xs[] = {"0", "5", "10", "15", "20", "30", "40", "50"};
00612   const Double_t xp[] = {0, 5, 10, 15, 20, 30, 40, 50};
00613   // Now draw the labels
00614   TLatex *p[8];
00615   for (int i = 0; i < 8; i++) {
00616     Double_t xpos;
00617     xpos = xp[i] <= 20 ? xp[i] : 20 + (xp[i]-20)/compress;
00618     //cout << "Drawing label " << xs[i] << " at " << xpos << endl;
00619     // Create a TLatex in a vaguely appropriate position
00620     p[i] = new TLatex(xpos, ymin-0.025*(ymax-ymin), xs[i]);
00621     p[i]->SetTextAlign(23);
00622     if (lsize > 0) {
00623       p[i]->SetTextFont(43);
00624       p[i]->SetTextSize(lsize);
00625     }
00626     else {
00627       p[i]->SetTextFont(42);
00628       p[i]->SetTextSize(0.06);
00629     }
00630     p[i]->Draw();
00631   }
00632 }
00633 
00634 //____________________________________________________________________72
00635 void NuMatrixSpectrum::CutLastBin()
00636 {
00637   double maxX = GetXaxis()->GetBinLowEdge(fSpectrum->GetNbinsX()) - 0.005;  
00638   SetRangeUser(0, maxX);
00639   cout << "Setting max X to " << maxX << endl;
00640 }
00641 
00642 
00643 //____________________________________________________________________72
00644 void NuMatrixSpectrum::ScaleToPot(double pot)
00645 {
00646   // Don't do anything unless we actually have POT
00647   if (fPoT < 1e-15) {
00648     return;
00649   }
00650 
00651   fSpectrum->Scale(pot/fPoT);
00652   fPoT = pot;
00653 }
00654 
00655 //____________________________________________________________________72
00656 void NuMatrixSpectrum::BlessedND()
00657 {
00658   static bool firstRun = true;
00659   if (firstRun) {
00660     cout << "Formatting blessed ND plot:" << endl
00661     << "* Binning scheme: ND Display (6) " << endl
00662     << "* PoT: 1e20 " << endl
00663     << "* Normalized to bin width" << endl
00664     << "* Events per 1 GeV" << endl
00665     << "* X axis compressed" << endl;
00666     firstRun = false;
00667   }
00668   RebinToScheme(NuBinningScheme::kDisplayND);
00669   ScaleToPot(1.e20);
00670   BinWidthNormalize();
00671   NuBarCompressX();
00672   fSpectrum->SetLineWidth(3);
00673 }
00674 
00675 //____________________________________________________________________72
00676 void NuMatrixSpectrum::BlessedFD(bool scale)
00677 {
00678   static bool firstRun = true;
00679   if (firstRun) {
00680     cout << "Formatting blessed FD plot:" << endl
00681          << "* Binning scheme: DisplayFD (5) " << endl;
00682     if (scale) cout << "* PoT: 3.2e20 " << endl;
00683     else       cout << "* PoT: Unchanged (" << PoT() << ")" << endl;
00684     cout << "* Normalized to bin width" << endl
00685          << "* Events per 4 GeV" << endl
00686          << "* X axis compressed" << endl;
00687     firstRun = false;
00688   }
00689   RebinToScheme(NuBinningScheme::kDisplayFD);
00690   if (scale) ScaleToPot(3.2e20);
00691   CalcPoisson();
00692   BinWidthNormalize();
00693   NuBarCompressX();
00694   fSpectrum->SetLineWidth(3);
00695 }
00696 
00697 //____________________________________________________________________72
00698 Double_t NuMatrixSpectrum::PoiErr(double y, bool up)
00699 {
00700   // Poisson Error Table
00701   Double_t jimeu[51];
00702   Double_t jimed[51];
00703   jimeu[0]=  1.841;  jimed[0]= 0.000;
00704   jimeu[1]=  3.3  ;  jimed[1]= 0.173;
00705   jimeu[2]=  4.638;  jimed[2]= 0.708;
00706   jimeu[3]=  5.918;  jimed[3]= 1.367;
00707   jimeu[4]=  7.163;  jimed[4]= 2.086;
00708   jimeu[5]=  8.382;  jimed[5]= 2.84 ;
00709   jimeu[6]=  9.584;  jimed[6]= 3.62 ;
00710   jimeu[7]=  10.77;  jimed[7]= 4.419;
00711   jimeu[8]=  11.95;  jimed[8]= 5.232;
00712   jimeu[9]=  13.11;  jimed[9]= 6.057;
00713   jimeu[10]= 14.27;  jimed[10]=6.891;
00714   jimeu[11]= 15.42;  jimed[11]=7.734;
00715   jimeu[12]= 16.56;  jimed[12]=8.585;
00716   jimeu[13]= 17.7;   jimed[13]=9.441;
00717   jimeu[14]= 18.83;  jimed[14]=10.3 ;
00718   jimeu[15]= 19.96;  jimed[15]=11.17;
00719   jimeu[16]= 21.08;  jimed[16]=12.04;
00720   jimeu[17]= 22.2 ;  jimed[17]=12.92;
00721   jimeu[18]= 23.32;  jimed[18]=13.8 ;
00722   jimeu[19]= 24.44;  jimed[19]=14.68;
00723   jimeu[20]= 25.55;  jimed[20]=15.57;
00724   jimeu[21]= 26.66;  jimed[21]=16.45;
00725   jimeu[22]= 27.76;  jimed[22]=17.35;
00726   jimeu[23]= 28.87;  jimed[23]=18.24;
00727   jimeu[24]= 29.97;  jimed[24]=19.14;
00728   jimeu[25]= 31.07;  jimed[25]=20.03;
00729   jimeu[26]= 32.16;  jimed[26]=20.93;
00730   jimeu[27]= 33.26;  jimed[27]=21.84;
00731   jimeu[28]= 34.35;  jimed[28]=22.74;
00732   jimeu[29]= 35.45;  jimed[29]=23.65;
00733   jimeu[30]= 36.54;  jimed[30]=24.55;
00734   jimeu[31]= 37.63;  jimed[31]=25.46;
00735   jimeu[32]= 38.72;  jimed[32]=26.37;
00736   jimeu[33]= 39.80;  jimed[33]=27.28;
00737   jimeu[34]= 40.89;  jimed[34]=28.20;
00738   jimeu[35]= 41.97;  jimed[35]=29.11;
00739   jimeu[36]= 43.06;  jimed[36]=30.03;
00740   jimeu[37]= 44.14;  jimed[37]=30.94;
00741   jimeu[38]= 45.22;  jimed[38]=31.86;
00742   jimeu[39]= 46.30;  jimed[39]=32.78;
00743   jimeu[40]= 47.32;  jimed[40]=33.70;
00744   jimeu[41]= 48.36;  jimed[41]=34.62;
00745   jimeu[42]= 49.53;  jimed[42]=35.55;
00746   jimeu[43]= 50.61;  jimed[43]=36.47;
00747   jimeu[44]= 51.68;  jimed[44]=37.39;
00748   jimeu[45]= 52.76;  jimed[45]=38.32;
00749   jimeu[46]= 53.83;  jimed[46]=39.24;
00750   jimeu[47]= 54.90;  jimed[47]=40.17;
00751   jimeu[48]= 55.98;  jimed[48]=41.10;
00752   jimeu[49]= 57.05;  jimed[49]=42.02;
00753   jimeu[50]= 58.12;  jimed[50]=42.95;
00754   
00755   Int_t n = TMath::Nint(y);
00756   Double_t err;
00757   if (up) err = jimeu[n] - n;
00758   else    err = n - jimed[n];
00759   
00760   return err;
00761 }
00762 
00763 
00764 //____________________________________________________________________72
00765 void NuMatrixSpectrum::CalcPoisson()
00766 {
00767   DoPoisson = true;
00768   
00769   const Int_t n = fSpectrum->GetNbinsX();
00770 
00771   Int_t y;
00772   for (Int_t i=1; i<=n; i++){
00773     y = TMath::Nint(fSpectrum->GetBinContent(i));
00774     PoiUp[i-1] = PoiErr(y, true);
00775     PoiDn[i-1] = PoiErr(y, false);
00776   }
00777 }
00778 
00779 
00780 //____________________________________________________________________72
00781 void NuMatrixSpectrum::DrawPoisson(Option_t* opt)
00782 {
00783   if (!DoPoisson) {
00784     MSG("NuMatrixSpectrum", Msg::kWarning) 
00785     << "CalcPoisson() not already called.  Poisson errors are being calculated based on current bin values."
00786     << endl;
00787     CalcPoisson();
00788   }
00789   
00790   TGraphAsymmErrors* g1 = new TGraphAsymmErrors(fSpectrum);
00791   
00792     
00793   double max = 0;
00794   for (Int_t i = 0; i< g1->GetN(); i++){
00795     Double_t x, y;
00796     g1->GetPoint(i, x, y);
00797     //cout << "i = " << i  << ", x = " << x << ", y = " << y 
00798     //     << ", PoiUp["<< i << "] = " << PoiUp[i] << endl;
00799     g1->SetPointEYlow(i, PoiDn[i]);
00800     g1->SetPointEYhigh(i, PoiUp[i]);
00801     if (y + PoiUp[i] > max) max = y+PoiUp[i];
00802   }
00803   TString option = "axis";
00804   option += opt;
00805   fSpectrum->Draw(option);
00806   g1->Draw("pe1same");
00807 }
00808 
00809 
00810 //____________________________________________________________________72
00811 Double_t NuMatrixSpectrum::IntegralVals(double low, double high, Option_t* option)
00812 {
00813   int binx1 = fSpectrum->GetXaxis()->FindFixBin(low);
00814   int binx2 = fSpectrum->GetXaxis()->FindFixBin(high);
00815   return Integral(binx1, binx2, option);
00816 }
00817 
00818 //____________________________________________________________________72
00819 void NuMatrixSpectrum::ExtrapolateNDToFD(const TH2D* correction)
00820 {
00821   this->XToY(correction);
00822 }
00823 
00824 //____________________________________________________________________72
00825 void NuMatrixSpectrum::XToY(const TH2D* correction)
00826 {
00827   const int NX = fSpectrum->GetNbinsX();
00828 
00829   if(correction->GetNbinsX() != NX || correction->GetNbinsY() != NX){
00830     MAXMSG("NuMatrixSpectrum", Msg::kError, 10)
00831       << "\n*** XToY: Correction has unexpected binning ***\n*** Expected "
00832       << NX << "x" << NX << " got "
00833       << correction->GetNbinsX() << "x" << correction->GetNbinsY() << " ***\n"
00834       << "*** Are all your spectra and matrices in consistent binnings? ***"
00835       << endl << endl;
00836   }
00837 
00838   //working space:
00839   Double_t *val = new Double_t[NX+1];
00840   for(int i=1;i<=NX+1;i++){
00841     val[i-1] = 0;
00842   }
00843   for(int i=1;i<=NX;i++){ //loop over true
00844     for(int j=1;j<=NX+1;j++){ //loop over reco
00845       val[j-1] += ( fSpectrum->GetBinContent(i) *
00846                     correction->GetBinContent(i,j));
00847     }
00848   }
00849   for(int i=1;i<=NX+1;i++) {
00850     fSpectrum->SetBinContent(i,val[i-1]);
00851   }
00852 
00853   delete[] val;
00854 }
00855 
00856 //____________________________________________________________________72
00857 void NuMatrixSpectrum::YToX(const TH2D* correction)
00858 {
00859   const int NX = fSpectrum->GetNbinsX();
00860 
00861   if(correction->GetNbinsY() != NX){
00862     MAXMSG("NuMatrixSpectrum", Msg::kError, 10)
00863       << "\n*** YToX: Correction has unexpected binning ***\n*** Expected "
00864       << NX << "x" << NX << " got "
00865       << correction->GetNbinsX() << "x" << correction->GetNbinsY() << " ***\n"
00866       << "*** Are all your spectra and matrices in consistent binnings? ***"
00867       << endl << endl;
00868   }
00869   
00870 
00871   //working space:
00872   Double_t *val = new Double_t[NX+1];
00873   for(int i=1;i<=NX+1;i++) { val[i-1] = 0; }
00874 
00875   const int NY = correction->GetNbinsY();
00876   for(int i=1;i<=NX;i++){
00877     for(int j=1;j<=NY;j++){
00878       val[j-1] += ( fSpectrum->GetBinContent(i) * 
00879                     correction->GetBinContent(j,i) );
00880     }
00881   }
00882   for(int i=1;i<=NX;i++) {
00883     fSpectrum->SetBinContent(i,val[i-1]);
00884   }
00885 
00886   delete[] val;
00887 }
00888 
00889 //____________________________________________________________________72
00890 void NuMatrixSpectrum::Oscillate(const Double_t dm2, const Double_t sn2)
00891 {
00892   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
00893     const Double_t energy = fSpectrum->GetBinCenter(i);
00894     const Double_t oscProb = NuUtilities::OscillationWeight(energy, dm2, sn2);
00895     fSpectrum->
00896       SetBinContent(i,fSpectrum->GetBinContent(i)*oscProb);
00897     fSpectrum->
00898       SetBinError(i,fSpectrum->GetBinError(i)*oscProb);
00899   }
00900 }
00901 
00902 //____________________________________________________________________72
00903 void NuMatrixSpectrum::OscillateHybrid(const Double_t dm2, Double_t sn2)
00904 {
00905   const Double_t threshold = 0.5; // The minimum spacing between oscillation minima/maxima
00906   Double_t minimum, previous;
00907   Int_t i = 2;
00908   minimum = (1.27 * 2 * (NuUtilities::FDDistance()/Munits::km) * dm2) / (1*TMath::Pi());
00909   // cout << "Initial min: " << minimum << endl;
00910   previous = minimum + threshold + 1;
00911   
00912   while (previous - minimum > threshold) {
00913     previous = minimum;
00914     minimum = (1.27 * 2 * (NuUtilities::FDDistance()/Munits::km) * dm2) / (i*TMath::Pi());
00915     ++i;
00916     // cout << i-1 << ": Min: " << minimum << ", Prev: " << previous << ", diff: " << previous - minimum << endl;
00917   }
00918   
00919   // cout << "Calculated cutoff energy: " << previous << endl;
00920   
00921   // Now min is the energy that we stop oscillating by center and start linear averaging
00922   for(int bin=1;bin<=fSpectrum->GetNbinsX();bin++) {
00923     Double_t oscProb = 0;
00924     
00925     Double_t energy = fSpectrum->GetBinCenter(bin);
00926     // cout << "Bin " << bin << ": ";
00927     // Check our cut-off point
00928     if (energy > previous) {
00929       // oscProb = 1. - (0.5 * sn2);
00930       oscProb = NuUtilities::OscillationWeight(energy, dm2, sn2);
00931      // cout << "Simple center-bin oscillation (" << energy << " = " << oscProb << "). ";
00932     } else {
00933       
00934       // cout << "Linear interpolation. ";
00938       // Use linear interpolation for the complicated parts
00939       const Double_t increment=0.001;
00940           
00941       if (1==bin || fSpectrum->GetNbinsX()==bin){
00942         // cout << "End bins. ";
00943         Int_t count=0;
00944         for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
00945              energy<fSpectrum->GetBinLowEdge(bin+1);
00946              energy+=increment){
00947           oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2);
00948           ++count;
00949         }
00950         oscProb /= count;
00951         //fSpectrum->SetBinContent(bin,
00952         //                       oscProb*fSpectrum->GetBinContent(bin));
00953         //fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
00954       }
00955       else{
00956         Double_t denominator=0.0;
00957         Double_t lowGrad =
00958           (fSpectrum->GetBinContent(bin)-fSpectrum->GetBinContent(bin-1))/
00959           (fSpectrum->GetBinWidth(bin)/2.0 + 
00960            fSpectrum->GetBinWidth(bin-1)/2.0);
00961         Double_t highGrad =
00962           (fSpectrum->GetBinContent(bin+1)-fSpectrum->GetBinContent(bin))/
00963           (fSpectrum->GetBinWidth(bin+1)/2.0 +
00964            fSpectrum->GetBinWidth(bin)/2.0);
00965         for (Double_t energy=fSpectrum->GetBinLowEdge(bin) + increment/2.0;
00966              energy<fSpectrum->GetBinLowEdge(bin+1);
00967              energy+=increment){
00968           if (energy<fSpectrum->GetBinCenter(bin)){
00969             oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2)*
00970               (fSpectrum->GetBinContent(bin-1) +
00971                lowGrad*(energy-fSpectrum->GetBinCenter(bin-1)));
00972             denominator +=
00973               fSpectrum->GetBinContent(bin-1) +
00974               lowGrad*(energy-fSpectrum->GetBinCenter(bin-1));
00975           }
00976           else {
00977             oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2)*
00978               (fSpectrum->GetBinContent(bin) +
00979                highGrad*(energy-fSpectrum->GetBinCenter(bin)));
00980             denominator +=
00981               fSpectrum->GetBinContent(bin) +
00982               highGrad*(energy-fSpectrum->GetBinCenter(bin));
00983           }
00984         }
00985         if (denominator>0){
00986           oscProb /= denominator;
00987         }
00988         else{
00989           oscProb = 0;
00990         }
00991       }
00992       
00997       
00998       
00999       
01000       
01001       
01002       
01003       
01004       
01005       
01006     }
01007     
01008     // cout << "Prob: " << oscProb << endl;
01009     // Now do the 'oscillation'
01010     fSpectrum->
01011       SetBinContent(bin,fSpectrum->GetBinContent(bin)*oscProb);
01012     fSpectrum->
01013       SetBinError(bin,fSpectrum->GetBinError(bin)*oscProb);
01014     
01015   }
01016 }
01017 //____________________________________________________________________72
01018 void NuMatrixSpectrum::OscillateSimpleAverage(const Double_t dm2,
01019                                               const Double_t sn2)
01020 {
01021   for (Int_t bin=1; bin<=fSpectrum->GetNbinsX(); bin++){
01022     Double_t oscProb=0.0;
01023     Double_t increment=0.001;
01024     Int_t count=0;
01025     for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
01026          energy<fSpectrum->GetBinLowEdge(bin+1);
01027          energy+=increment){
01028       oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2);
01029       ++count;
01030     }
01031     oscProb /= count;
01032     fSpectrum->SetBinContent(bin,
01033                              oscProb*fSpectrum->GetBinContent(bin));
01034     fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01035   }
01036 }
01037 
01038 //____________________________________________________________________72
01039 void NuMatrixSpectrum::OscillateLinearInterp(const Double_t dm2,
01040                                              const Double_t sn2)
01041 {
01042   for (Int_t bin=1; bin<=fSpectrum->GetNbinsX(); bin++){
01043     Double_t oscProb=0.0;
01044     Double_t increment=0.001;
01045     if (1==bin || fSpectrum->GetNbinsX()==bin){
01046       Int_t count=0;
01047       for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
01048            energy<fSpectrum->GetBinLowEdge(bin+1);
01049            energy+=increment){
01050         oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2);
01051         ++count;
01052       }
01053       oscProb /= count;
01054       //fSpectrum->SetBinContent(bin,
01055       //                       oscProb*fSpectrum->GetBinContent(bin));
01056       //fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01057     }
01058     else{
01059       Double_t denominator=0.0;
01060       Double_t lowGrad =
01061         (fSpectrum->GetBinContent(bin)-fSpectrum->GetBinContent(bin-1))/
01062         (fSpectrum->GetBinWidth(bin)/2.0 + 
01063          fSpectrum->GetBinWidth(bin-1)/2.0);
01064       Double_t highGrad =
01065         (fSpectrum->GetBinContent(bin+1)-fSpectrum->GetBinContent(bin))/
01066         (fSpectrum->GetBinWidth(bin+1)/2.0 +
01067          fSpectrum->GetBinWidth(bin)/2.0);
01068       for (Double_t energy=fSpectrum->GetBinLowEdge(bin) + increment/2.0;
01069            energy<fSpectrum->GetBinLowEdge(bin+1);
01070            energy+=increment){
01071         if (energy<fSpectrum->GetBinCenter(bin)){
01072           oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2)*
01073             (fSpectrum->GetBinContent(bin-1) +
01074              lowGrad*(energy-fSpectrum->GetBinCenter(bin-1)));
01075           denominator +=
01076             fSpectrum->GetBinContent(bin-1) +
01077             lowGrad*(energy-fSpectrum->GetBinCenter(bin-1));
01078         }
01079         else {
01080           oscProb += NuUtilities::OscillationWeight(energy, dm2, sn2)*
01081             (fSpectrum->GetBinContent(bin) +
01082              highGrad*(energy-fSpectrum->GetBinCenter(bin)));
01083           denominator +=
01084             fSpectrum->GetBinContent(bin) +
01085             highGrad*(energy-fSpectrum->GetBinCenter(bin));
01086         }
01087       }
01088       if (denominator>0){
01089         oscProb /= denominator;
01090       }
01091       else{
01092         oscProb = 0;
01093       }
01094     }
01095   fSpectrum->SetBinContent(bin,oscProb*fSpectrum->GetBinContent(bin));
01096   fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01097   }
01098 }
01099 
01100 //____________________________________________________________________72
01101 void NuMatrixSpectrum::InverseOscillate(const Double_t dm2,
01102                                         const Double_t sn2)
01103 {
01104   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
01105     Double_t energy = fSpectrum->GetBinCenter(i);
01106     Double_t oscProb = 1-NuUtilities::OscillationWeight(energy, dm2, sn2);
01107     fSpectrum->
01108       SetBinContent(i,fSpectrum->GetBinContent(i)*oscProb);
01109     fSpectrum->
01110       SetBinError(i,fSpectrum->GetBinError(i)*oscProb);
01111   }
01112 }
01113 
01114 //____________________________________________________________________72
01115 void NuMatrixSpectrum::InverseOscillateHybrid(const Double_t dm2, Double_t sn2)
01116 {
01117   // Calculate the cut-off point
01118   const Double_t threshold = 0.25; // The minimum spacing between oscillation minima/maxima
01119   Double_t minimum, previous;
01120   Int_t i = 2;
01121   minimum = (1.27 * 2 * (NuUtilities::FDDistance()/Munits::km) * dm2) / (1*TMath::Pi());
01122   // cout << "Initial min: " << minimum << endl;
01123   previous = minimum + threshold + 1;
01124   
01125   while (previous - minimum > threshold) {
01126     previous = minimum;
01127     minimum = (1.27 * 2 * (NuUtilities::FDDistance()/Munits::km) * dm2) / (i*TMath::Pi());
01128     ++i;
01129     // cout << i-1 << ": Min: " << minimum << ", Prev: " << previous << ", diff: " << previous - minimum << endl;
01130   }
01131   
01132   // Now min is the energy that we stop oscillating and start normalising
01133   for(int bin=1;bin<=fSpectrum->GetNbinsX();bin++) {
01134     Double_t energy = fSpectrum->GetBinCenter(bin);
01135     Double_t oscProb = 0;
01136     
01137     const Double_t increment=0.001;
01138         
01139     // Check our cut-off point
01140     if (energy > previous) {
01141       oscProb = 1-NuUtilities::OscillationWeight(energy, dm2, sn2);
01142     } else {
01143       
01147       
01148       if (1==bin || fSpectrum->GetNbinsX()==bin){
01149         Int_t count=0;
01150         for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
01151              energy<fSpectrum->GetBinLowEdge(bin+1);
01152              energy+=increment){
01153           oscProb += 1-NuUtilities::OscillationWeight(energy, dm2, sn2);
01154           ++count;
01155         }
01156         oscProb /= count;
01157         //fSpectrum->SetBinContent(bin,
01158         //        oscProb*fSpectrum->GetBinContent(bin));
01159         //fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01160       }
01161       else{
01162         Double_t denominator=0.0;
01163         Double_t lowGrad =
01164           (fSpectrum->GetBinContent(bin)-fSpectrum->GetBinContent(bin-1))/
01165           (fSpectrum->GetBinWidth(bin)/2.0 + 
01166            fSpectrum->GetBinWidth(bin-1)/2.0);
01167         Double_t highGrad =
01168           (fSpectrum->GetBinContent(bin+1)-fSpectrum->GetBinContent(bin))/
01169           (fSpectrum->GetBinWidth(bin+1)/2.0 +
01170            fSpectrum->GetBinWidth(bin)/2.0);
01171         for (Double_t energy=fSpectrum->GetBinLowEdge(bin) + increment/2.0;
01172              energy<fSpectrum->GetBinLowEdge(bin+1);
01173              energy+=increment){
01174           if (energy<fSpectrum->GetBinCenter(bin)){
01175             oscProb += (1-NuUtilities::OscillationWeight(energy, dm2, sn2))*
01176               (fSpectrum->GetBinContent(bin-1) +
01177                lowGrad*(energy-fSpectrum->GetBinCenter(bin-1)));
01178             denominator +=
01179               fSpectrum->GetBinContent(bin-1) +
01180               lowGrad*(energy-fSpectrum->GetBinCenter(bin-1));
01181           }
01182           else {
01183             oscProb += (1-NuUtilities::OscillationWeight(energy, dm2, sn2))*
01184               (fSpectrum->GetBinContent(bin) +
01185                highGrad*(energy-fSpectrum->GetBinCenter(bin)));
01186             denominator +=
01187               fSpectrum->GetBinContent(bin) +
01188               highGrad*(energy-fSpectrum->GetBinCenter(bin));
01189           }
01190         }
01191         if (denominator>0){
01192           oscProb /= denominator;
01193         }
01194         else{
01195           oscProb = 0;
01196         }
01197       }
01198       
01202     }
01203     
01204     fSpectrum->
01205       SetBinContent(bin,fSpectrum->GetBinContent(bin)*oscProb);
01206     fSpectrum->
01207       SetBinError(bin,fSpectrum->GetBinError(bin)*oscProb);
01208     
01209   }
01210 }
01211 
01212 //____________________________________________________________________72
01213 void NuMatrixSpectrum::InverseOscillateSimpleAverage(const Double_t dm2,
01214                                                      const Double_t sn2)
01215 {
01216   for (Int_t bin=1; bin<=fSpectrum->GetNbinsX(); bin++){
01217     Double_t oscProb=0.0;
01218     Double_t increment=0.001;
01219     Int_t count=0;
01220     for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
01221          energy<fSpectrum->GetBinLowEdge(bin+1);
01222          energy+=increment){
01223       oscProb += 1-NuUtilities::OscillationWeight(energy, dm2, sn2);
01224       ++count;
01225     }
01226     oscProb /= count;
01227     fSpectrum->SetBinContent(bin,
01228                              oscProb*fSpectrum->GetBinContent(bin));
01229     fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01230   }
01231 }
01232 
01233 //____________________________________________________________________72
01234 void NuMatrixSpectrum::InverseOscillateLinearInterp(const Double_t dm2,
01235                                                     const Double_t sn2)
01236 {
01237   for (Int_t bin=1; bin<=fSpectrum->GetNbinsX(); bin++){
01238     Double_t oscProb=0.0;
01239     Double_t increment=0.001;
01240     if (1==bin || fSpectrum->GetNbinsX()==bin){
01241       Int_t count=0;
01242       for (Double_t energy = fSpectrum->GetBinLowEdge(bin)+increment/2.0;
01243            energy<fSpectrum->GetBinLowEdge(bin+1);
01244            energy+=increment){
01245         oscProb += 1-NuUtilities::OscillationWeight(energy, dm2, sn2);
01246         ++count;
01247       }
01248       oscProb /= count;
01249       //fSpectrum->SetBinContent(bin,
01250       //        oscProb*fSpectrum->GetBinContent(bin));
01251       //fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01252     }
01253     else{
01254       Double_t denominator=0.0;
01255       Double_t lowGrad =
01256         (fSpectrum->GetBinContent(bin)-fSpectrum->GetBinContent(bin-1))/
01257         (fSpectrum->GetBinWidth(bin)/2.0 + 
01258          fSpectrum->GetBinWidth(bin-1)/2.0);
01259       Double_t highGrad =
01260         (fSpectrum->GetBinContent(bin+1)-fSpectrum->GetBinContent(bin))/
01261         (fSpectrum->GetBinWidth(bin+1)/2.0 +
01262          fSpectrum->GetBinWidth(bin)/2.0);
01263       for (Double_t energy=fSpectrum->GetBinLowEdge(bin) + increment/2.0;
01264            energy<fSpectrum->GetBinLowEdge(bin+1);
01265            energy+=increment){
01266         if (energy<fSpectrum->GetBinCenter(bin)){
01267           oscProb += (1-NuUtilities::OscillationWeight(energy, dm2, sn2))*
01268             (fSpectrum->GetBinContent(bin-1) +
01269              lowGrad*(energy-fSpectrum->GetBinCenter(bin-1)));
01270           denominator +=
01271             fSpectrum->GetBinContent(bin-1) +
01272             lowGrad*(energy-fSpectrum->GetBinCenter(bin-1));
01273         }
01274         else {
01275           oscProb += (1-NuUtilities::OscillationWeight(energy, dm2, sn2))*
01276             (fSpectrum->GetBinContent(bin) +
01277              highGrad*(energy-fSpectrum->GetBinCenter(bin)));
01278           denominator +=
01279             fSpectrum->GetBinContent(bin) +
01280             highGrad*(energy-fSpectrum->GetBinCenter(bin));
01281         }
01282       }
01283       if (denominator>0){
01284         oscProb /= denominator;
01285       }
01286       else{
01287         oscProb = 0;
01288       }
01289     }
01290   fSpectrum->SetBinContent(bin,oscProb*fSpectrum->GetBinContent(bin));
01291   fSpectrum->SetBinError(bin, oscProb*fSpectrum->GetBinError(bin));
01292   }
01293 }
01294 
01295 /*
01296 //____________________________________________________________________72
01297 void NuMatrixSpectrum::DecaySimpleAverage(const Double_t alpha,
01298                                           const Double_t sn2)
01299 {
01300   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
01301     const Double_t energy = fSpectrum->GetBinCenter(i);
01302     const Double_t decayProb = NuUtilities::DecayWeight(energy, alpha, sn2);
01303     fSpectrum->
01304       SetBinContent(i,fSpectrum->GetBinContent(i)*decayProb);
01305     fSpectrum->
01306       SetBinError(i,fSpectrum->GetBinError(i)*decayProb);
01307   }
01308 }
01309 */
01310 
01311 //____________________________________________________________________72
01312 void NuMatrixSpectrum::DecayCC(const Double_t alpha,
01313                              const Double_t sn2)
01314 {
01315   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
01316     const Double_t energy = fSpectrum->GetBinCenter(i);
01317     const Double_t decayProb = NuUtilities::DecayWeightCC(energy, alpha, sn2);
01318     fSpectrum->
01319       SetBinContent(i,fSpectrum->GetBinContent(i)*decayProb);
01320     fSpectrum->
01321       SetBinError(i,fSpectrum->GetBinError(i)*decayProb);
01322   }
01323 }
01324 
01325 //____________________________________________________________________72
01326 void NuMatrixSpectrum::DecayNC(const Double_t alpha,
01327                                const Double_t sn2)
01328 {
01329   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
01330     const Double_t energy = fSpectrum->GetBinCenter(i);
01331     const Double_t decayProb = NuUtilities::DecayWeightNC(energy, alpha, sn2);
01332     fSpectrum->
01333       SetBinContent(i,fSpectrum->GetBinContent(i)*decayProb);
01334     fSpectrum->
01335       SetBinError(i,fSpectrum->GetBinError(i)*decayProb);
01336   }
01337 }
01338 
01339 //____________________________________________________________________72
01340 void NuMatrixSpectrum::Decohere(const Double_t mu2,
01341                                 const Double_t sn2)
01342 {
01343   for(int i=1;i<=fSpectrum->GetNbinsX();i++) {
01344     const Double_t energy = fSpectrum->GetBinCenter(i);
01345     const Double_t decoherenceProb = NuUtilities::DecoherenceWeight(energy, mu2, sn2);
01346     fSpectrum->
01347       SetBinContent(i,fSpectrum->GetBinContent(i)*decoherenceProb);
01348     fSpectrum->
01349       SetBinError(i,fSpectrum->GetBinError(i)*decoherenceProb);
01350   }
01351 }
01352 
01353 //____________________________________________________________________72
01354 void NuMatrixSpectrum::Add(const TH1D* correction)
01355 {
01356   // If we don't have a spectrum, copy it
01357   if (!fSpectrum) {
01358     fSpectrum = new TH1D(*correction);
01359   } else {
01360     // Just add it
01361     fSpectrum->Add(correction);
01362   }
01363 }
01364 
01365 //____________________________________________________________________72
01366 void NuMatrixSpectrum::Add(const NuMatrixSpectrum& correction, bool addPot)
01367 {
01368   this->Add(correction.fSpectrum);
01369   // fSpectrum->Add(correction.fSpectrum);
01370   if (addPot) fPoT += correction.PoT();
01371 }
01372 
01373 //____________________________________________________________________72
01374 void NuMatrixSpectrum::Subtract(const TH1D* correction)
01375 {
01376   fSpectrum->Add(correction, -1.0);
01377 }
01378 
01379 //____________________________________________________________________72
01380 void NuMatrixSpectrum::Subtract(const NuMatrixSpectrum& correction)
01381 {
01382   fSpectrum->Add(correction.fSpectrum, -1.0);
01383 }
01384 
01385 
01386 //____________________________________________________________________72
01387 void NuMatrixSpectrum::RebinToArray(std::vector<Double_t> &bins)
01388 {
01389   TH1D* tmp = NuUtilities::RebinHistogram(fSpectrum, bins);  
01390   ResetSpectrum(*tmp);
01391   delete tmp;
01392 }
01393 
01394 //____________________________________________________________________72
01395 void NuMatrixSpectrum::RebinToArray(int nbins, const double binedges[999])
01396 {
01397   TH1D* tmp = NuUtilities::RebinHistogram(fSpectrum, nbins, binedges);  
01398   ResetSpectrum(*tmp);
01399   delete tmp;
01400 }
01401 
01402 //____________________________________________________________________72
01403 void NuMatrixSpectrum::RebinToScheme(int scheme)
01404 {
01405   RebinToScheme(static_cast<NuBinningScheme::NuBinningScheme_t>(scheme));
01406 }
01407 
01408 //____________________________________________________________________72
01409 void NuMatrixSpectrum::RebinToScheme(NuBinningScheme::NuBinningScheme_t scheme)
01410 {
01411   TH1D* tmp = NuUtilities::RebinHistogram(fSpectrum, scheme);  
01412   ResetSpectrum(*tmp);
01413   delete tmp;  
01414 }
01415 
01416 //____________________________________________________________________72
01417 void NuMatrixSpectrum::RebinToGeV(Double_t binwidth)
01418 {
01419   double edges[] = {0, 200};
01420   double steps[] = {binwidth};
01421   vector<Double_t> bins = NuUtilities::GenerateBins(1, edges, steps);
01422   this->RebinToArray(bins);
01423 }
01424 
01425 //____________________________________________________________________72
01426 void NuMatrixSpectrum::RebinForFit()
01427 {
01428   double edges[] = {0,   10,  20, 30, 50, 200};
01429   double steps[] = {0.5, 1.0, 10, 20, 150};
01430   vector<Double_t> bins = NuUtilities::GenerateBins(5, edges, steps);
01431   this->RebinToArray(bins);
01432 }
01433 
01434 
01435 //____________________________________________________________________72
01436 void NuMatrixSpectrum::RebinForPlotAsFit()
01437 {
01438   double edges[] = {0,   10,  20, 30, 50, 200};
01439   double steps[] = {0.5, 1.0, 10, 20, 150};
01440   vector<Double_t> bins = NuUtilities::GenerateBins(5, edges, steps);
01441   this->RebinToArray(bins);
01442   this->BinWidthNormalize();
01443   this->CompressTopBins();
01444 }
01445 
01446 //____________________________________________________________________72
01447 void NuMatrixSpectrum::RebinForPlots()
01448 {
01449   double edges[] = {0,   10,  20, 30, 50, 200};
01450   double steps[] = {1.0, 2.0, 10, 20, 150};
01451   vector<Double_t> bins = NuUtilities::GenerateBins(5, edges, steps);
01452   this->RemoveErrors();
01453   this->GenerateErrors();
01454   this->RebinToArray(bins);
01455   this->BinWidthNormalize();
01456   this->CompressTopBins();  
01457 }  
01458 
01459 //____________________________________________________________________72
01460 NuMatrixSpectrum * NuMatrixSpectrum::Fluctuate()
01461 {
01462   NuMatrixSpectrum *fluctSpect = new NuMatrixSpectrum(*this);
01463   fluctSpect->FluctuateMe();
01464   return fluctSpect;
01465 }
01466 
01467 //____________________________________________________________________72
01468 void NuMatrixSpectrum::FluctuateMe()
01469 {
01470   static NuFluctuator *fl = 0;
01471   if (!fl) {
01472     fl = new NuFluctuator();
01473   }
01474   
01475   TH1D tmp = fl->Fluctuate(this->Spectrum());
01476   ResetSpectrum(tmp);
01477 }
01478 
01479 

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