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

NuUtilities.cxx

Go to the documentation of this file.
00001 
00002 
00003 // Coded by Justin Evans from February 2008 onwards
00004 //
00005 // Contact: justin.evans@ucl.ac.uk
00007 
00008 #include <cmath>
00009 #include <glob.h>
00010 #include <sstream>
00011 
00012 #include <sys/stat.h>
00013 
00014 
00015 #include "Rtypes.h"
00016 #include "TFile.h"
00017 #include "TMath.h"
00018 
00019 #include "Conventions/Detector.h"
00020 #include "Conventions/Munits.h"
00021 #include "Conventions/ReleaseType.h"
00022 #include "Conventions/SimFlag.h"
00023 #include "MessageService/MsgService.h"
00024 #include "NuMuBar/NuConfig.h"
00025 #include "NtupleUtils/NuMatrixSpectrum.h"
00026 #include "NtupleUtils/NuUtilities.h"
00027 #include "NtupleUtils/NuEvent.h"
00028 #include "NtupleUtils/NuLibrary.h"
00029 
00030 CVSID("$Id: NuUtilities.cxx,v 1.35 2010/02/01 14:41:15 bckhouse Exp $");
00031 
00032 //____________________________________________________________________72
00033 NuUtilities::NuUtilities()
00034 {
00035 }
00036 
00037 //____________________________________________________________________72
00038 NuUtilities::~NuUtilities()
00039 {
00040 }
00041 
00042 //____________________________________________________________________72
00043 void NuUtilities::CalcFiducialMass()
00044 {
00045 
00046 
00047   const Float_t avPlSteelDensityNDData=7.847*(Munits::g/Munits::cm3);
00048   const Float_t avPlSteelThicknessNDData=2.563*(Munits::cm);
00049   const Float_t avPlScintDensityNDData=1.0457*(Munits::g/Munits::cm3);
00050   const Float_t avPlScintThicknessNDData=1.02*(Munits::cm);
00051   const Float_t avPlAlumDensityNDData=2.7*(Munits::g/Munits::cm3);
00052   const Float_t avPlAlumThicknessNDData=0.1*(Munits::cm);
00053 
00054   const Float_t avPlSteelDensityFDData=avPlSteelDensityNDData;
00055   const Float_t avPlSteelThicknessFDData=2.559*(Munits::cm);
00056   const Float_t avPlScintDensityFDData=avPlScintDensityNDData;
00057   const Float_t avPlScintThicknessFDData=avPlScintThicknessNDData;
00058   const Float_t avPlAlumDensityFDData=avPlAlumDensityNDData;
00059   const Float_t avPlAlumThicknessFDData=avPlAlumThicknessNDData;
00060 
00061   //MC
00062   const Float_t avPlSteelDensityNDMC=avPlSteelDensityNDData;
00063   const Float_t avPlSteelThicknessNDMC=2.54*(Munits::cm);
00064   const Float_t avPlScintDensityNDMC=avPlScintDensityNDData;
00065   const Float_t avPlScintThicknessNDMC=1.0*(Munits::cm);
00066   const Float_t avPlAlumDensityNDMC=avPlAlumDensityNDData;
00067   const Float_t avPlAlumThicknessNDMC=avPlAlumThicknessNDData;
00068 
00069   const Float_t avPlSteelDensityFDMC=avPlSteelDensityNDMC;
00070   const Float_t avPlSteelThicknessFDMC=avPlSteelThicknessNDMC;
00071   const Float_t avPlScintDensityFDMC=avPlScintDensityNDMC;
00072   const Float_t avPlScintThicknessFDMC=avPlScintThicknessNDMC;
00073   const Float_t avPlAlumDensityFDMC=avPlAlumDensityNDMC;
00074   const Float_t avPlAlumThicknessFDMC=avPlAlumThicknessNDMC;
00075 
00076   cout<<"************** Thickness and Density ******************"<<endl;
00077   cout<<"Thickness ND Data:"
00078       <<" steel="<<avPlSteelThicknessNDData
00079       <<", scint="<<avPlScintThicknessNDData
00080       <<", alum="<<avPlAlumThicknessNDData<<endl;
00081   cout<<"Density ND Data:"
00082       <<" steel="<<avPlSteelDensityNDData
00083       <<", scint="<<avPlScintDensityNDData
00084       <<", alum="<<avPlAlumDensityNDData<<endl;
00085   cout<<endl;
00086     cout<<"Thickness ND MC:"
00087       <<" steel="<<avPlSteelThicknessNDMC
00088       <<", scint="<<avPlScintThicknessNDMC
00089       <<", alum="<<avPlAlumThicknessNDMC<<endl;
00090   cout<<"Density ND MC:"
00091       <<" steel="<<avPlSteelDensityNDMC
00092       <<", scint="<<avPlScintDensityNDMC
00093       <<", alum="<<avPlAlumDensityNDMC<<endl;
00094 
00095   cout<<endl<<endl;
00096   cout<<"Thickness FD Data:"
00097       <<" steel="<<avPlSteelThicknessFDData
00098       <<", scint="<<avPlScintThicknessFDData
00099       <<", alum="<<avPlAlumThicknessFDData<<endl;
00100   cout<<"Density FD Data:"
00101       <<" steel="<<avPlSteelDensityFDData
00102   <<", scint="<<avPlScintDensityFDData
00103       <<", alum="<<avPlAlumDensityFDData<<endl;
00104   cout<<endl;
00105     cout<<"Thickness FD MC:"
00106       <<" steel="<<avPlSteelThicknessFDMC
00107       <<", scint="<<avPlScintThicknessFDMC
00108       <<", alum="<<avPlAlumThicknessFDMC<<endl;
00109   cout<<"Density FD MC:"
00110       <<" steel="<<avPlSteelDensityFDMC
00111       <<", scint="<<avPlScintDensityFDMC
00112       <<", alum="<<avPlAlumDensityFDMC<<endl;
00113 
00114   const Float_t avPlSteelStPwNDData=
00115     avPlSteelThicknessNDData*avPlSteelDensityNDData;
00116   const Float_t avPlScintStPwNDData=
00117     avPlScintThicknessNDData*avPlScintDensityNDData;
00118   const Float_t avPlAlumStPwNDData=
00119     avPlAlumThicknessNDData*avPlAlumDensityNDData;
00120 
00121   const Float_t avPlSteelStPwFDData=
00122     avPlSteelThicknessFDData*avPlSteelDensityFDData;
00123   const Float_t avPlScintStPwFDData=
00124     avPlScintThicknessFDData*avPlScintDensityFDData;
00125   const Float_t avPlAlumStPwFDData=
00126     avPlAlumThicknessFDData*avPlAlumDensityFDData;
00127 
00128   const Float_t avPlSteelStPwNDMC=
00129     avPlSteelThicknessNDMC*avPlSteelDensityNDMC;
00130   const Float_t avPlScintStPwNDMC=
00131     avPlScintThicknessNDMC*avPlScintDensityNDMC;
00132   const Float_t avPlAlumStPwNDMC=
00133     avPlAlumThicknessNDMC*avPlAlumDensityNDMC;
00134 
00135   const Float_t avPlSteelStPwFDMC=
00136     avPlSteelThicknessFDMC*avPlSteelDensityFDMC;
00137   const Float_t avPlScintStPwFDMC=
00138     avPlScintThicknessFDMC*avPlScintDensityFDMC;
00139   const Float_t avPlAlumStPwFDMC=
00140     avPlAlumThicknessFDMC*avPlAlumDensityFDMC;
00141 
00142   cout<<endl<<endl;
00143   cout<<"**************** Stopping Power ********************"<<endl;
00144   cout<<"StPw ND Data:"
00145       <<" steel="<<avPlSteelStPwNDData
00146       <<", scint="<<avPlScintStPwNDData
00147       <<", alum="<<avPlAlumStPwNDData<<endl;
00148   cout<<endl;
00149   cout<<"StPw ND MC:"
00150       <<" steel="<<avPlSteelStPwNDMC
00151       <<", scint="<<avPlScintStPwNDMC
00152       <<", alum="<<avPlAlumStPwNDMC<<endl;
00153   cout<<endl<<endl;
00154   cout<<"StPw FD Data:"
00155       <<" steel="<<avPlSteelStPwFDData
00156       <<", scint="<<avPlScintStPwFDData
00157       <<", alum="<<avPlAlumStPwFDData<<endl;
00158   cout<<endl;
00159   cout<<"StPw FD MC:"
00160       <<" steel="<<avPlSteelStPwFDMC
00161       <<", scint="<<avPlScintStPwFDMC
00162       <<", alum="<<avPlAlumStPwFDMC<<endl;
00163 
00164 
00165   //NOW CALC AREAS
00166   Float_t areaPlND=3.142*pow(0.8*Munits::m,2);
00167   Float_t areaPlFD=3.142*(14*Munits::m2-pow(0.4*Munits::m,2));
00168   cout<<endl<<endl;
00169   cout<<"Area ND = "<<areaPlND<<endl;
00170   cout<<"Area FD = "<<areaPlFD<<endl;
00171 
00172   //NOW CALC MASS
00173   const Float_t avPlSteelMassNDData=avPlSteelStPwNDData*areaPlND;
00174   const Float_t avPlScintMassNDData=avPlScintStPwNDData*areaPlND;
00175   const Float_t avPlAlumMassNDData=avPlAlumStPwNDData*areaPlND;
00176 
00177   const Float_t avPlSteelMassNDMC=avPlSteelStPwNDMC*areaPlND;
00178   const Float_t avPlScintMassNDMC=avPlScintStPwNDMC*areaPlND;
00179   const Float_t avPlAlumMassNDMC=avPlAlumStPwNDMC*areaPlND;
00180 
00181   const Float_t avPlSteelMassFDData=avPlSteelStPwFDData*areaPlFD;
00182   const Float_t avPlScintMassFDData=avPlScintStPwFDData*areaPlFD;
00183   const Float_t avPlAlumMassFDData=avPlAlumStPwFDData*areaPlFD;
00184 
00185   const Float_t avPlSteelMassFDMC=avPlSteelStPwFDMC*areaPlFD;
00186   const Float_t avPlScintMassFDMC=avPlScintStPwFDMC*areaPlFD;
00187   const Float_t avPlAlumMassFDMC=avPlAlumStPwFDMC*areaPlFD;
00188 
00189   cout<<endl<<endl;
00190   cout<<"**************** MASS ********************"<<endl;
00191   cout<<"Mass ND Data:"
00192       <<" steel="<<avPlSteelMassNDData
00193       <<", scint="<<avPlScintMassNDData
00194       <<", alum="<<avPlAlumMassNDData<<endl;
00195   cout<<endl;
00196   cout<<"Mass ND MC:"
00197       <<" steel="<<avPlSteelMassNDMC
00198       <<", scint="<<avPlScintMassNDMC
00199       <<", alum="<<avPlAlumMassNDMC<<endl;
00200   cout<<endl<<endl;
00201   cout<<"Mass FD Data:"
00202       <<" steel="<<avPlSteelMassFDData
00203       <<", scint="<<avPlScintMassFDData
00204       <<", alum="<<avPlAlumMassFDData<<endl;
00205   cout<<endl;
00206   cout<<"Mass FD MC:"
00207       <<" steel="<<avPlSteelMassFDMC
00208       <<", scint="<<avPlScintMassFDMC
00209       <<", alum="<<avPlAlumMassFDMC<<endl;
00210 
00211 
00212 
00213   const Float_t avPlTotalMassNDData=
00214     avPlSteelMassNDData+avPlScintMassNDData+avPlAlumMassNDData;
00215   const Float_t avPlTotalMassNDMC=
00216     avPlSteelMassNDMC+avPlScintMassNDMC+avPlAlumMassNDMC;
00217   const Float_t avPlTotalMassFDData=
00218     avPlSteelMassFDData+avPlScintMassFDData+avPlAlumMassFDData;
00219   const Float_t avPlTotalMassFDMC=
00220     avPlSteelMassFDMC+avPlScintMassFDMC+avPlAlumMassFDMC;
00221 
00222   const Float_t massSumND=avPlTotalMassNDData+avPlTotalMassNDMC;
00223   const Float_t massSumFD=avPlTotalMassFDData+avPlTotalMassFDMC;
00224   const Float_t massDiffND=avPlTotalMassNDData-avPlTotalMassNDMC;
00225   const Float_t massDiffFD=avPlTotalMassFDData-avPlTotalMassFDMC;
00226 
00227   const Float_t massRelDiffND=massDiffND/(0.5*massSumND);
00228   const Float_t massRelDiffFD=massDiffFD/(0.5*massSumFD);
00229 
00230   cout<<endl<<endl;
00231   cout<<"Mass ND Data Total: "<<avPlTotalMassNDData<<endl;
00232   cout<<"Mass ND MC Total: "<<avPlTotalMassNDMC<<endl;
00233   cout<<"Mass ND Data-MC="<<massDiffND<<endl;
00234   cout<<"Mass ND Data-MC/(0.5*Data+MC)="<<massRelDiffND<<endl;
00235   cout<<endl;
00236   cout<<"Mass FD Data Total: "<<avPlTotalMassFDData<<endl;
00237   cout<<"Mass FD MC Total: "<<avPlTotalMassFDMC<<endl;
00238   cout<<"Mass FD Data-MC="<<massDiffFD<<endl;
00239   cout<<"Mass FD Data-MC/(0.5*Data+MC)="<<massRelDiffFD<<endl;
00240   cout<<endl;
00241 
00242   //Considering events from STEEL planes
00243   //ND: 14->68 inclusive = 55 planes of steel
00244   cout<<endl<<endl;
00245   cout<<"55 planes in ND Data="
00246       <<55*avPlTotalMassNDData/(Munits::kilotonne)<<" kilotonnes"<<endl;
00247   cout<<"55 planes in ND MC  ="
00248       <<55*avPlTotalMassNDMC/(Munits::kilotonne)<<" kilotonnes"<<endl;
00249 
00250   //FD: 4->239 inclusive + 253->464 inclusive = 236 + 212 = 448 planes
00251   cout<<endl<<endl;
00252   cout<<"448 planes in FD Data="
00253       <<448*avPlTotalMassFDData/(Munits::kilotonne)<<" kilotonnes"
00254       <<endl;
00255   cout<<"448 planes in FD MC  ="
00256       <<448*avPlTotalMassFDMC/(Munits::kilotonne)<<" kilotonnes"
00257       <<endl;
00258 
00259 
00260 //Table 5 of minos-doc-3134v2 has updated numbers
00261 //Both detectors have the same densities in MC
00262 //steel = 7.847
00263 //scint = 1.0457, thickness=1.0cm
00264 //The pitches of ND and FD are slightly different
00265 
00266 //Peter Litchfield's email of 20/06/07 22:27 GMT
00267 //Real detectors
00268 //Plane pitch  FD (average) 5.946cm,  ND 5.94cm (3134)
00269 //Steel density  Both Detectors 7.847gm/cc (1431)
00270 //Steel thickness FD 2.559cm, ND 2.563cm (1529)
00271 //Scintillator 1.02cm density 1.0457gm/cc (scint+coating, 3134)
00272 //Aluminium    0.1cm  density 2.7gm/cc (PDG book)
00273 //FD average density = 3.602gm/cc
00274 //ND average density = 3.611gm/cc
00275 
00276 //In the Birch MC (3134)
00277 //Plane pitch  FD (average) 5.946cm,  ND 5.94cm
00278 //Steel density 7.87gm/cc
00279 //Steel thickness 2.54cm
00280 //Scintillator 1.02cm density 1.032gm/cc
00281 //Aluminium 0.1cm air, negligible density
00282 //FD avearge density = 3.539gm/cc
00283 //ND average density = 3.542gm/cc
00284 }
00285 
00286 //____________________________________________________________________72
00287 TString NuUtilities::PrintRelease(int releaseType)
00288 {
00289   char hexnum[20];
00290   sprintf(hexnum, "%x", releaseType);
00291   TString ret = ReleaseType::AsString(releaseType);
00292   ret += " (0x";
00293   ret += hexnum;
00294   ret += ", ";
00295   ret += releaseType;
00296   ret += ")";
00297   return ret;
00298 }
00299 
00300 
00301 //____________________________________________________________________72
00302 const BeamType::BeamType_t NuUtilities::ReturnConventionsBeamType
00303 (const NuConfig& config)
00304 {
00305   if (Detector::kFar==config.detector && SimFlag::kData==config.simFlag){
00306     MAXMSG("NuUtilities",Msg::kInfo,1)
00307       << "Detected FD data, so not combining intensity with beamType"
00308       << endl;
00309     BeamType::BeamType_t originalBeamType =
00310       static_cast<BeamType::BeamType_t>(config.beamType);
00311     return originalBeamType;
00312   }
00313   else{
00314     return NuUtilities::ConvertToConventionsBeamType(config.beamType,
00315                                                      config.intensity);
00316   }
00317 }
00318 
00319 //____________________________________________________________________72
00320 const BeamType::BeamType_t NuUtilities::ConvertToConventionsBeamType
00321 (const Int_t beamType, const Int_t intensity)
00322 {
00323   BeamType::BeamType_t originalBeamType =
00324     static_cast<BeamType::BeamType_t>(beamType);
00325   if (0==intensity){
00326     return originalBeamType;
00327   }
00328   if (BeamType::kL010z185i == originalBeamType){
00329     if (124==intensity){
00330       return BeamType::kL010z185i_i124;
00331     }
00332     else if (191==intensity){
00333       return BeamType::kL010z185i_i191;
00334     }
00335     else if (213==intensity){
00336       return BeamType::kL010z185i_i213;
00337     }
00338     else if (224==intensity){
00339       return BeamType::kL010z185i_i224;
00340     }
00341     else if (232==intensity){
00342       return BeamType::kL010z185i_i232;
00343     }
00344     else if (243==intensity){
00345       return BeamType::kL010z185i_i243;
00346     }
00347     else if (257==intensity){
00348       return BeamType::kL010z185i_i257;
00349     }
00350     else if (282==intensity){
00351       return BeamType::kL010z185i_i282;
00352     }
00353     else if (303==intensity){
00354       return BeamType::kL010z185i_i303;
00355     }
00356     else if (324==intensity){
00357       return BeamType::kL010z185i_i324;
00358     }
00359     else {
00360       MSG("NuUtilities",Msg::kWarning)
00361         << "Received an L010z185i beam type with unrecognized intensity. Intensity = "
00362         << intensity
00363         << endl;
00364       return BeamType::kUnknown;
00365     }
00366   }
00367 
00368   if (BeamType::kL010z000i == originalBeamType){
00369     if (209 == intensity){
00370       return BeamType::kL010z000i_i209;
00371     }
00372     else if (225 == intensity){
00373       return BeamType::kL010z000i_i225;
00374     }
00375     else if (232 == intensity){
00376       return BeamType::kL010z000i_i232;
00377     }
00378     else if (259 == intensity){
00379       return BeamType::kL010z000i_i259;
00380     }
00381     else if (300 == intensity){
00382       return BeamType::kL010z000i_i300;
00383     }
00384     else if (317 == intensity){
00385       return BeamType::kL010z000i_i317;
00386     }
00387     else if (326 == intensity){
00388       return BeamType::kL010z000i_i326;
00389     }
00390     else if (380 == intensity){
00391       return BeamType::kL010z000i_i380;
00392     }
00393     else {
00394       MSG("NuUtilities",Msg::kWarning)
00395         << "Received an L010z000i beam type with unrecognized intensity."
00396         << endl;
00397       return BeamType::kUnknown;
00398     }
00399   }
00400 
00401   if (BeamType::kL250z200i == originalBeamType){
00402     if (100 == intensity){
00403       return BeamType::kL250z200i_i100;
00404     }
00405     else if (114 == intensity){
00406       return BeamType::kL250z200i_i114;
00407     }
00408     else if (130 == intensity){
00409       return BeamType::kL250z200i_i130;
00410     }
00411     else if (152 == intensity){
00412       return BeamType::kL250z200i_i152;
00413     }
00414     else if (165 == intensity){
00415       return BeamType::kL250z200i_i165;
00416     }
00417     else if (194 == intensity){
00418       return BeamType::kL250z200i_i194;
00419     }
00420     else if (232 == intensity){
00421       return BeamType::kL250z200i_i232;
00422     }
00423     else {
00424       MSG("NuUtilities",Msg::kWarning)
00425         << "Received an L250z200i beam type with unrecognized intensity."
00426         << endl;
00427       return BeamType::kUnknown;
00428     }
00429   }
00430 
00431   MSG("NuUtilities",Msg::kWarning)
00432     << "Received a non-zero intensity flag, along with a beam "
00433     << "type not configured for intensity weighting."
00434     << endl;
00435   return BeamType::kUnknown;
00436 
00437 }
00438 
00439 //____________________________________________________________________72
00440 const vector<Double_t> NuUtilities::GenerateBins(int ngroups, double edges[], double steps[])
00441 {
00442     vector<Double_t> bins;
00443     for (int g = 0; g < ngroups; g++) {
00444         Double_t lowEdge = edges[g];
00445         Double_t highEdge = edges[g+1];
00446         Double_t binWidth = steps[g];
00447         for (Double_t binEdge = lowEdge;
00448              binEdge < highEdge - (binWidth/2.0);
00449              binEdge += binWidth){
00450             bins.push_back(binEdge);
00451         }
00452     }
00453     bins.push_back(edges[ngroups]);
00454     return bins;
00455 }
00456 
00457 
00458 //____________________________________________________________________72
00459 const vector<Double_t> NuUtilities::RecoBins
00460 (const NuBinningScheme::NuBinningScheme_t binningScheme)
00461 {
00462   if (NuBinningScheme::kUnknown == binningScheme ||
00463       NuBinningScheme::k0_5GeVTo200 == binningScheme){
00464     MAXMSG("NuUtilities",Msg::kInfo,5)
00465       << "Binning reco energy in 0.5 GeV up to 200 GeV" << endl;
00466     vector<Double_t> bins;
00467     Double_t lowEdge = 0.0;
00468     Double_t highEdge = 200.0;
00469     Double_t binWidth = 0.5;
00470     for (Double_t binEdge = lowEdge;
00471          binEdge <= highEdge + (binWidth/2.0);
00472          binEdge += binWidth){
00473       bins.push_back(binEdge);
00474     }
00475     return bins;
00476   }
00477   else if (NuBinningScheme::kCC0325Std == binningScheme){
00478     MAXMSG("NuUtilities",Msg::kInfo,5)
00479       << "Reco energy: one bin from 0.0--0.5, "
00480       << "then 0.25 GeV bins up to 200.0 GeV"
00481       << endl;
00482     vector<Double_t> bins;
00483     bins.push_back(0.0);
00484     Double_t lowEdge = 0.5;
00485     Double_t highEdge = 200.0;
00486     Double_t binWidth = 0.25;
00487     for (Double_t binEdge = lowEdge;
00488          binEdge <= highEdge + (binWidth/2.0);
00489          binEdge += binWidth){
00490       bins.push_back(binEdge);
00491     }
00492     return bins;
00493   }
00494   else if (NuBinningScheme::kNuMuBar0325Std == binningScheme){
00495     MAXMSG("NuUtilities",Msg::kInfo,5)
00496       << "Reco energy: 0.5 GeV up to 30 GeV; 2 GeV up to 50 GeV; "
00497       << "1 bin up to 200 GeV"
00498       << endl;
00499     vector<Double_t> bins;
00500     Double_t lowEdge = 0.0;
00501     Double_t highEdge = 30.0;
00502     Double_t binWidth = 0.5;
00503     for (Double_t binEdge = lowEdge;
00504          binEdge < highEdge - (binWidth/2.0);
00505          binEdge += binWidth){
00506       bins.push_back(binEdge);
00507     }
00508     lowEdge = 30.0;
00509     highEdge = 50.0;
00510     binWidth = 2.0;
00511     for (Double_t binEdge = lowEdge;
00512          binEdge < highEdge - (binWidth/2.0);
00513          binEdge += binWidth){
00514       bins.push_back(binEdge);
00515     }
00516     bins.push_back(50.0);
00517     bins.push_back(200.0);
00518     return bins;
00519   }
00520   else if (NuBinningScheme::kNuMuBar0325Std2 == binningScheme)
00521   {
00522     MAXMSG("NuUtilities",Msg::kInfo,5)
00523       << "Reco Energy: One 0.5 GeV, then 0.25 GeV up to 20 GeV; "
00524       << "1 Gev to 30 GeV,\n 2 GeV from 30 to 50 GeV; One 150 GeV bin to 200 GeV"
00525       << endl;
00526     vector<Double_t> bins;
00527     bins.push_back(0.0);
00528     Double_t lowEdge = 0.5;
00529     Double_t highEdge = 20.0;
00530     Double_t binWidth = 0.25;
00531     for (Double_t binEdge = lowEdge;
00532           binEdge < highEdge -(binWidth/2.0);
00533           binEdge += binWidth) {
00534       bins.push_back(binEdge);
00535     }
00536     lowEdge = 20.0;
00537     highEdge = 30.0;
00538     binWidth = 1.0;
00539     for (Double_t binEdge = lowEdge;
00540           binEdge < highEdge -(binWidth/2.0);
00541           binEdge += binWidth) {
00542       bins.push_back(binEdge);
00543     }
00544     lowEdge = 30.0;
00545     highEdge = 50.0;
00546     binWidth = 2.0;
00547     for (Double_t binEdge = lowEdge;
00548           binEdge < highEdge -(binWidth/2.0);
00549           binEdge += binWidth) {
00550       bins.push_back(binEdge);
00551     }
00552     bins.push_back(50.0);
00553     bins.push_back(200.0);
00554     return bins;
00555   }
00556   else if (NuBinningScheme::kDisplayFD == binningScheme) {
00557     MAXMSG("NuUtilities",Msg::kInfo,5)
00558     << "Reco Energy: 4 GeV Bins up to 20 GeV, then 20, 30, 50, 200"
00559     << endl;
00560     vector<Double_t> bins;
00561     Double_t lowEdge = 0.0;
00562     Double_t highEdge = 20.0;
00563     Double_t binWidth = 4;
00564     for (Double_t binEdge = lowEdge;
00565          binEdge < highEdge -(binWidth/2.0);
00566          binEdge += binWidth) {
00567       bins.push_back(binEdge);
00568     }
00569     bins.push_back(20.0);
00570     bins.push_back(30.0);
00571     bins.push_back(50.0);
00572     bins.push_back(200.0);
00573     return bins;
00574   }
00575   else if (NuBinningScheme::kDisplayND == binningScheme) {
00576     MAXMSG("NuUtilities",Msg::kInfo,5)
00577     << "Reco Energy: 1 Gev to 30 GeV, 2 GeV from 30 to 50 GeV; One 150 GeV bin to 200 GeV"
00578     << endl;
00579     vector<Double_t> bins;
00580     Double_t lowEdge = 0.0;
00581     Double_t highEdge = 20.0;
00582     Double_t binWidth = 1.0;
00583     for (Double_t binEdge = lowEdge;
00584          binEdge < highEdge -(binWidth/2.0);
00585          binEdge += binWidth) {
00586       bins.push_back(binEdge);
00587     }
00588     lowEdge = 20.0;
00589     highEdge = 30.0;
00590     binWidth = 2.0;
00591     for (Double_t binEdge = lowEdge;
00592          binEdge < highEdge -(binWidth/2.0);
00593          binEdge += binWidth) {
00594       bins.push_back(binEdge);
00595     }
00596     lowEdge = 30.0;
00597     highEdge = 50.0;
00598     binWidth = 4.0;
00599     for (Double_t binEdge = lowEdge;
00600          binEdge < highEdge -(binWidth/2.0);
00601          binEdge += binWidth) {
00602       bins.push_back(binEdge);
00603     }
00604     bins.push_back(50.0);
00605     bins.push_back(200.0);
00606     return bins;
00607   }
00608   else {
00609     MAXMSG("NuUtilities",Msg::kInfo,100)
00610     << "!!Invalid binning scheme (" << binningScheme << ") requested.!!" << endl
00611     << "Binning reco energy in 0.5 GeV up to 200 GeV" << endl;
00612     vector<Double_t> bins;
00613     Double_t lowEdge = 0.0;
00614     Double_t highEdge = 200.0;
00615     Double_t binWidth = 0.5;
00616     for (Double_t binEdge = lowEdge;
00617          binEdge <= highEdge + (binWidth/2.0);
00618          binEdge += binWidth){
00619       bins.push_back(binEdge);
00620     }
00621     return bins;
00622   }
00623 }
00624 
00625 //____________________________________________________________________72
00626 const vector<Double_t> NuUtilities::TrueBins
00627 (const NuBinningScheme::NuBinningScheme_t binningScheme)
00628 {
00629   if (NuBinningScheme::kUnknown == binningScheme ||
00630       NuBinningScheme::k0_5GeVTo200 == binningScheme){
00631     MAXMSG("NuUtilities",Msg::kInfo,5)
00632       << "Binning true energy in 0.5 GeV up to 200 GeV" << endl;
00633     vector<Double_t> bins;
00634     Double_t lowEdge = 0.0;
00635     Double_t highEdge = 200.0;
00636     Double_t binWidth = 0.5;
00637     for (Double_t binEdge = lowEdge;
00638          binEdge <= highEdge + (binWidth/2.0);
00639          binEdge += binWidth){
00640       bins.push_back(binEdge);
00641     }
00642     return bins;
00643   }
00644   else if (NuBinningScheme::kCC0325Std == binningScheme){
00645     MAXMSG("NuUtilities",Msg::kInfo,5)
00646       << "True energy: one bin from 0.0--0.5, "
00647       << "then 0.25 GeV bins up to 200.0 GeV"
00648       << endl;
00649     vector<Double_t> bins;
00650     bins.push_back(0.0);
00651     Double_t lowEdge = 0.5;
00652     Double_t highEdge = 200.0;
00653     Double_t binWidth = 0.25;
00654     for (Double_t binEdge = lowEdge;
00655          binEdge <= highEdge + (binWidth/2.0);
00656          binEdge += binWidth){
00657       bins.push_back(binEdge);
00658     }
00659     return bins;
00660   }
00661   else if (NuBinningScheme::kNuMuBar0325Std == binningScheme){
00662     MAXMSG("NuUtilities",Msg::kInfo,5)
00663       << "True energy: 0.5 GeV up to 30 GeV; 2 GeV up to 50 GeV; "
00664       << "1 bin up to 200 GeV"
00665       << endl;
00666     vector<Double_t> bins;
00667     Double_t lowEdge = 0.0;
00668     Double_t highEdge = 30.0;
00669     Double_t binWidth = 0.5;
00670     for (Double_t binEdge = lowEdge;
00671          binEdge < highEdge - (binWidth/2.0);
00672          binEdge += binWidth){
00673       bins.push_back(binEdge);
00674     }
00675     lowEdge = 30.0;
00676     highEdge = 50.0;
00677     binWidth = 2.0;
00678     for (Double_t binEdge = lowEdge;
00679          binEdge < highEdge - (binWidth/2.0);
00680          binEdge += binWidth){
00681       bins.push_back(binEdge);
00682     }
00683     bins.push_back(50.0);
00684     bins.push_back(200.0);
00685     return bins;
00686   }
00687   else if (NuBinningScheme::kNuMuBar0325Std2 == binningScheme) {
00688     MAXMSG("NuUtilities",Msg::kInfo,5)
00689       << "True Energy: One 0.5 GeV, then 0.25 GeV up to 20 GeV; "
00690       << "1 Gev to 30 GeV,\n 2 GeV from 30 to 50 GeV; One 150 GeV bin to 200 GeV"
00691       << endl;
00692     vector<Double_t> bins;
00693     bins.push_back(0.0);
00694     Double_t lowEdge = 0.5;
00695     Double_t highEdge = 20.0;
00696     Double_t binWidth = 0.25;
00697     for (Double_t binEdge = lowEdge;
00698           binEdge < highEdge -(binWidth/2.0);
00699           binEdge += binWidth) {
00700       bins.push_back(binEdge);
00701     }
00702     lowEdge = 20.0;
00703     highEdge = 30.0;
00704     binWidth = 1.0;
00705     for (Double_t binEdge = lowEdge;
00706           binEdge < highEdge -(binWidth/2.0);
00707           binEdge += binWidth) {
00708       bins.push_back(binEdge);
00709     }
00710     lowEdge = 30.0;
00711     highEdge = 50.0;
00712     binWidth = 2.0;
00713     for (Double_t binEdge = lowEdge;
00714           binEdge < highEdge -(binWidth/2.0);
00715           binEdge += binWidth) {
00716       bins.push_back(binEdge);
00717     }
00718     bins.push_back(50.0);
00719     bins.push_back(200.0);
00720     return bins;
00721   }
00722   else if (NuBinningScheme::kDisplayFD == binningScheme) {
00723     MAXMSG("NuUtilities",Msg::kInfo,5)
00724     << "True Energy: 4 GeV Bins up to 20 GeV, then 20, 30, 50, 200"
00725     << endl;
00726     vector<Double_t> bins;
00727     Double_t lowEdge = 0.0;
00728     Double_t highEdge = 20.0;
00729     Double_t binWidth = 4;
00730     for (Double_t binEdge = lowEdge;
00731          binEdge < highEdge -(binWidth/2.0);
00732          binEdge += binWidth) {
00733       bins.push_back(binEdge);
00734     }
00735     bins.push_back(20.0);
00736     bins.push_back(30.0);
00737     bins.push_back(50.0);
00738     bins.push_back(200.0);
00739     return bins;
00740   }
00741   else if (NuBinningScheme::kDisplayND == binningScheme) {
00742     MAXMSG("NuUtilities",Msg::kInfo,5)
00743     << "Reco Energy: 1 Gev to 30 GeV, 2 GeV from 30 to 50 GeV; One 150 GeV bin to 200 GeV"
00744     << endl;
00745     vector<Double_t> bins;
00746     Double_t lowEdge = 0.0;
00747     Double_t highEdge = 20.0;
00748     Double_t binWidth = 1.0;
00749     for (Double_t binEdge = lowEdge;
00750          binEdge < highEdge -(binWidth/2.0);
00751          binEdge += binWidth) {
00752       bins.push_back(binEdge);
00753     }
00754     lowEdge = 20.0;
00755     highEdge = 30.0;
00756     binWidth = 2.0;
00757     for (Double_t binEdge = lowEdge;
00758          binEdge < highEdge -(binWidth/2.0);
00759          binEdge += binWidth) {
00760       bins.push_back(binEdge);
00761     }
00762     lowEdge = 30.0;
00763     highEdge = 50.0;
00764     binWidth = 4.0;
00765     for (Double_t binEdge = lowEdge;
00766          binEdge < highEdge -(binWidth/2.0);
00767          binEdge += binWidth) {
00768       bins.push_back(binEdge);
00769     }
00770     bins.push_back(50.0);
00771     bins.push_back(200.0);
00772     return bins;
00773   }
00774   else {
00775     MAXMSG("NuUtilities",Msg::kInfo,100)
00776     << "!!Invalid binning scheme requested.!!" << endl
00777     << "Binning true energy in 0.5 GeV up to 200 GeV" << endl;
00778     vector<Double_t> bins;
00779     Double_t lowEdge = 0.0;
00780     Double_t highEdge = 200.0;
00781     Double_t binWidth = 0.5;
00782     for (Double_t binEdge = lowEdge;
00783          binEdge <= highEdge + (binWidth/2.0);
00784          binEdge += binWidth){
00785       bins.push_back(binEdge);
00786     }
00787     return bins;
00788   }
00789 }
00790 
00791 //____________________________________________________________________72
00792 void NuUtilities::WriteHistosToFile(const std::vector<TH1D>& vHistos,
00793                                     TFile& file)
00794 {
00795   file.cd();
00796   for (vector<TH1D>::const_iterator it = vHistos.begin();
00797        it != vHistos.end();
00798        ++it){
00799     (*it).Write();
00800     cout << "Written " << (*it).GetName() << endl;
00801   }
00802 }
00803 
00804 //____________________________________________________________________72
00805 void NuUtilities::WriteHistosToFile(const std::vector<NuMatrixSpectrum>& vHistos,
00806                                     TFile& file)
00807 {
00808   file.cd();
00809   for (vector<NuMatrixSpectrum>::const_iterator it = vHistos.begin();
00810        it != vHistos.end();
00811        ++it){
00812     (*it).Spectrum()->Write();
00813     cout << "Written " << (*it).GetName() << endl;
00814   }
00815 }
00816 
00817 
00818 //____________________________________________________________________72
00819 TH1D* NuUtilities::RebinHistogram(const TH1D* old, int nbins, const double binedges[999])
00820 {
00821   static int count = 0;
00822   TString scount = "";
00823   scount += count++;
00824 
00825   TH1D *newh = new TH1D(old->GetName()+TString("_rebin")+scount, old->GetTitle(), nbins, binedges);
00826   bool ouwarn = true;
00827 
00828   // Now, loop over the old histogram and fill the new one
00829   for(Int_t bin = 1; bin <= old->GetNbinsX(); bin++) {
00830 
00831     double oldCent = old->GetBinLowEdge(bin);
00832     int newbin = newh->GetXaxis()->FindFixBin(oldCent);
00833 
00834     // Make sure that bins do not cross boundaries.
00835     if (newbin > newh->GetNbinsX() || newbin == 0) {
00836       if (ouwarn) {
00837         cout << "Old bin: " << old->GetBinLowEdge(bin) << " - " << old->GetBinLowEdge(bin+1)
00838         << " and maybe others have become under/overflow" << endl;
00839         ouwarn = false;
00840       }
00841     }
00842     else if ( old->GetBinLowEdge(bin) < newh->GetBinLowEdge(newbin) ||
00843         old->GetBinLowEdge(bin+1) > newh->GetBinLowEdge(newbin+1)) {
00844       cout << "Bin edge conflict in bin no's " << bin << ", " << newbin << ".  No rebinning performed."
00845            << "  old bin: " << old->GetBinLowEdge(bin) << " - " << old->GetBinLowEdge(bin+1)
00846            << ", new bin: " << newh->GetBinLowEdge(newbin) << " - " << newh->GetBinLowEdge(newbin+1)
00847            << endl;
00848       TH1D *old_ret = new TH1D(*old);
00849       return old_ret;
00850     }
00851 
00852     double oldCon = old->GetBinContent(bin);
00853     double oldErr = old->GetBinError(bin);
00854     double newCon = newh->GetBinContent(newbin);
00855     double newErr = newh->GetBinError(newbin);
00856 
00857     newCon += oldCon;
00858     newErr = sqrt(newErr*newErr + oldErr*oldErr);
00859     newh->SetBinContent(newbin, newCon);
00860     newh->SetBinError(newbin, newErr);
00861   }
00862 
00863   // Validate
00864   double oldint = old->Integral();
00865   double newint = newh->Integral() + newh->GetBinContent(0)
00866                  + newh->GetBinContent(newh->GetNbinsX()+1);
00867   if (abs(oldint - newint) > 1e-5) {
00868     cout << "Rebinning report: " << oldint << " entries have become " << newint << " events" << endl;
00869   }
00870   //newh->Sumw2();
00871   return newh;
00872 }
00873 
00874 
00875 //____________________________________________________________________72
00876 TH1D* NuUtilities::RebinHistogram(const TH1D* old, std::vector<Double_t> &bins)
00877 {
00878   return RebinHistogram(old, bins.size()-1, &(bins[0]));
00879 }
00880 
00881 //____________________________________________________________________72
00882 TH1D* NuUtilities::RebinHistogram(const TH1D* old, NuBinningScheme::NuBinningScheme_t scheme)
00883 {
00884   vector<Double_t> bins = RecoBins(scheme);
00885   return RebinHistogram(old, bins);
00886 }
00887 
00888 
00889 template<class T> inline T SQR(T x){return x*x;}
00890 
00891 
00892 //____________________________________________________________________72
00893 Double_t NuUtilities::OscillationWeight(const Double_t energy,
00894                                         const Double_t dm2,
00895                                         const Double_t sn2)
00896 {
00897   return 1-sn2*SQR(sin(1.27*dm2*(FDDistance()/Munits::km)/energy));
00898 }
00899 
00900 
00901 //____________________________________________________________________72
00902 Double_t NuUtilities::DecayWeightCC(const Double_t energy,
00903                                   const Double_t alpha,
00904                                   const Double_t sn2)
00905 {
00906   return SQR(sn2+(1-sn2)*exp(-(alpha*FDDistance()/Munits::km)/(2*energy)));
00907 }
00908 
00909 
00910 //____________________________________________________________________72
00911 Double_t NuUtilities::DecayWeightNC(const Double_t energy,
00912                                     const Double_t alpha,
00913                                     const Double_t sn2)
00914 {
00915   return (1-sn2)+sn2*exp(-(alpha*FDDistance()/Munits::km)/energy);
00916 }
00917 
00918 
00919 //____________________________________________________________________72
00920 Double_t NuUtilities::DecoherenceWeight(const Double_t energy,
00921                                         const Double_t mu2,
00922                                         const Double_t sn2)
00923 {
00924   return 1-(sn2/2)*(1-exp(-(mu2*FDDistance()/Munits::km)/(2*energy)));
00925 }
00926 
00927 //____________________________________________________________________72
00928 void NuUtilities::FixDogwoodQP(NuEvent &nu)
00929 {
00930   // Only need to fix dogwood NuEvent's
00931   if (!ReleaseType::IsDogwood(nu.recoVersion)) {
00932     MAXMSG("NuUtilities",Msg::kInfo,5) << "Not correcting q/p for "
00933     << PrintRelease(nu.recoVersion) << endl;
00934     return;
00935   }
00936   MAXMSG("NuUtilities",Msg::kInfo,5) << "Correcting "
00937   << PrintRelease(nu.recoVersion) << " q/p from "
00938   << nu.qp << " to " << nu.qp_rangebiased << endl;
00939 
00940   nu.qp = nu.qp_rangebiased;
00941   if (nu.sigqp == 0) nu.qp_sigqp = 0;
00942   else               nu.qp_sigqp = nu.qp_rangebiased / nu.sigqp;
00943 
00944   nu.qp1 = nu.qp_rangebiased1;
00945   if (nu.sigqp1 == 0) nu.qp_sigqp1 = 0;
00946   else                nu.qp_sigqp1 = nu.qp_rangebiased1 / nu.sigqp1;
00947 
00948   nu.qp2 = nu.qp_rangebiased2;
00949   if (nu.sigqp2 == 0) nu.qp_sigqp2 = 0;
00950   else                nu.qp_sigqp2 = nu.qp_rangebiased2 / nu.sigqp2;
00951 
00952   nu.qp3 = nu.qp_rangebiased3;
00953   if (nu.sigqp3 == 0) nu.qp_sigqp3 = 0;
00954   else                nu.qp_sigqp3 = nu.qp_rangebiased3 / nu.sigqp3;
00955 
00956   if (nu.qp_sigqp == 0) nu.sigqp_qp = 0;
00957   else                  nu.sigqp_qp = 1./nu.qp_sigqp;
00958 
00959   NuLibrary& lib=NuLibrary::Instance();
00960   lib.reco.GetEvtEnergy(nu, false);
00961 
00962   if (nu.qp_rangebiased > 0) nu.charge = 1;
00963   else                       nu.charge = -1;
00964 }
00965 
00966 //____________________________________________________________________72
00967 std::vector<TString> NuUtilities::
00968   GetListOfFilesInDir(const TString &wildcardString)
00969 {
00970   std::vector<TString> fileList;
00971 
00972   glob_t g;
00973   glob(wildcardString.Data(),
00974        // GLOB_NOCHECK | // If no match return pattern
00975        GLOB_TILDE, // Expand ~'s
00976        0, &g);
00977   for(unsigned int i = 0; i < g.gl_pathc; ++i)
00978     fileList.push_back(g.gl_pathv[i]);
00979   globfree(&g);
00980 
00981   // glob output is sorted by default
00982 
00983   return fileList;
00984 }
00985 //____________________________________________________________________72
00986 
00987 Double_t NuUtilities::LogLikelihood(Double_t dnu, Double_t mnu)
00988 {
00989   if (dnu) {
00990     // Protection against cases where there is data but no MC?
00991     // This should not normally be possible, other than highly contrived
00992     // unphysical oscillation values.
00993     // Set the value to something lower than POT_Data / POT_MC, which at the
00994     // moment is usually 1e-3. We can justify this as an error on the MC
00995     const Double_t MCError = 1e-7;
00996     if (mnu < MCError) mnu = MCError;
00997         
00998     // We have both values. Do the proper lnL!
00999     return 2*(mnu - dnu + dnu*log(dnu/mnu));
01000   } else {
01001     // dnu is zero, mnu may or may not be zero
01002     return 2*mnu;
01003   }
01004 }
01005 
01006 
01007 //____________________________________________________________________72
01008 
01009 int NuUtilities::GetDigit(int num, int d) 
01010 { 
01011   int pow1 = static_cast<int>(TMath::Power(10, d));
01012   int pow2 = pow1 / 10;
01013   return (num % pow1 - num % pow2) / pow2; 
01014 }
01015 
01016 
01017 
01018 //____________________________________________________________________72
01019 
01020 void NuUtilities::ProgressBar(Int_t entry, Float_t nEntriesF, Int_t mintime)
01021 {
01022   Int_t nEntries = (Int_t)nEntriesF;
01023     
01024   // Are we streaming to a file? If so, show the old style
01025   struct stat buf;
01026   fstat(fileno(stdout), &buf);
01027   // Check if we are a file, or a pipe (i.e. in case the user tees)
01028   const bool isFile = buf.st_mode & (S_IFREG | S_IFIFO) ;
01029   if (isFile) {
01030     Float_t fract = ceil(nEntries/20.);  
01031     if (ceil(((Float_t)entry)/fract)==((Float_t)entry)/fract)
01032     {
01033         MSG("NuUtilities",Msg::kInfo) 
01034           <<"Fraction of loop complete: "<<entry 
01035           <<"/"<<nEntries<<"  ("
01036           <<(Int_t)(100.*entry/nEntries)<<"%)"<<endl;
01037     }
01038     return;
01039   }
01040   
01041   
01042   // How wide should we make the progress bar?
01043   const Int_t width = 70;
01044   // How long is the string for entries?
01045   static Int_t countlen = -1;
01046   // How long is our progress bar?
01047   static Int_t barlen = -1;
01048   // The entry number of the next bar entry
01049   static Int_t nextbar = -1;
01050   // When did we start?
01051   static time_t starttime = 0;
01052   // when do we next update?
01053   static time_t nextupdate = 0;
01054   // If we are processing the first entry, reset everything
01055   if (entry <= 1)
01056   {
01057     // Get the new length of the entry string
01058     countlen = (Int_t)TMath::Ceil(TMath::Log10(nEntries)) + 1;
01059     nextbar = -1;
01060     starttime = time(NULL);
01061 
01062     barlen = width - 14 - countlen*2 - 1;
01063 
01064     // Don't update until we get to the minimum time
01065     nextupdate = starttime + mintime;
01066   }
01067 
01068   // Check here to see if we should update; otherwise, return
01069   // Check to see if the bar would update
01070   // or, alternatively, it is time to refresh.
01071   if ((time(NULL) < nextupdate) && (entry < nextbar || (nextbar == -1)))return;
01072   nextupdate = time(NULL) + 10;
01073 
01074   // Because this is used in several places, make it here
01075   Float_t frac = (Float_t)entry / (Float_t)nEntries;
01076 
01077   // Prepare the progress bar string
01078   TString bar;
01079   if (entry <= nEntries)
01080   {
01081     // Work out how many characters we are in
01082     Int_t numeq = TMath::FloorNint(frac*barlen);
01083 
01084     // Work out when the next bar will occur
01085     nextbar = (Int_t)((Float_t)(numeq+1)/(Float_t)barlen*nEntries);
01086     //cout << "Next bar at: " << nextbar << "        " << endl;
01087     bar = TString('=', numeq);
01088     bar += TString(' ', barlen - numeq);
01089   } else if (entry > nEntries) {
01090     // We have gone over. Oh no!
01091     bar = TString('+', barlen);
01092   } else if (entry < 0) {
01093     // Somehow, we are below zero. Handle it nonetheless
01094     bar = TString('-', barlen);
01095   }
01096 
01097 
01098   // Prepare the ETA
01099   Float_t elapsed_time = (Float_t)(time(NULL) - starttime);
01100   Float_t time_left = -60;
01101   if (frac > 1e-6) {
01102     time_left = (elapsed_time / frac) - elapsed_time;
01103   }
01104   Int_t mins, seconds;
01105   mins    = (Int_t)TMath::Floor(time_left / 60.0f);
01106   seconds = (Int_t)TMath::Floor(time_left - (Float_t)(mins*60.0f));
01107   // TString ETA;
01108   ostringstream ETA;
01109 
01110   ETA << "ETA ";
01111   if ((mins < 0 || seconds < 0) || (mins == 0 && seconds == 0)) {
01112     ETA << "--:--";
01113   } else {
01114     ETA << setfill('0') << setw(2) << mins << ":" << setw(2) << seconds;
01115   }
01116 
01117   cout << " Progress: [" << bar << "] "
01118        << setw(countlen) << entry << "/" << nEntries
01119        << " " << ETA.str()
01120        << '\r'
01121        << flush;
01122   // Move to the next line, if this is the final entry!
01123   if (entry == nEntries) {
01124     cout << endl;
01125   }
01126 }

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