00001
00002
00003
00004
00005
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
00033 NuUtilities::NuUtilities()
00034 {
00035 }
00036
00037
00038 NuUtilities::~NuUtilities()
00039 {
00040 }
00041
00042
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
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
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
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
00243
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
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
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 }
00285
00286
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
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
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
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
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
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
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
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
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
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
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
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
00871 return newh;
00872 }
00873
00874
00875
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
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
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
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
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
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
00928 void NuUtilities::FixDogwoodQP(NuEvent &nu)
00929 {
00930
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
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
00975 GLOB_TILDE,
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
00982
00983 return fileList;
00984 }
00985
00986
00987 Double_t NuUtilities::LogLikelihood(Double_t dnu, Double_t mnu)
00988 {
00989 if (dnu) {
00990
00991
00992
00993
00994
00995 const Double_t MCError = 1e-7;
00996 if (mnu < MCError) mnu = MCError;
00997
00998
00999 return 2*(mnu - dnu + dnu*log(dnu/mnu));
01000 } else {
01001
01002 return 2*mnu;
01003 }
01004 }
01005
01006
01007
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
01019
01020 void NuUtilities::ProgressBar(Int_t entry, Float_t nEntriesF, Int_t mintime)
01021 {
01022 Int_t nEntries = (Int_t)nEntriesF;
01023
01024
01025 struct stat buf;
01026 fstat(fileno(stdout), &buf);
01027
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
01043 const Int_t width = 70;
01044
01045 static Int_t countlen = -1;
01046
01047 static Int_t barlen = -1;
01048
01049 static Int_t nextbar = -1;
01050
01051 static time_t starttime = 0;
01052
01053 static time_t nextupdate = 0;
01054
01055 if (entry <= 1)
01056 {
01057
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
01065 nextupdate = starttime + mintime;
01066 }
01067
01068
01069
01070
01071 if ((time(NULL) < nextupdate) && (entry < nextbar || (nextbar == -1)))return;
01072 nextupdate = time(NULL) + 10;
01073
01074
01075 Float_t frac = (Float_t)entry / (Float_t)nEntries;
01076
01077
01078 TString bar;
01079 if (entry <= nEntries)
01080 {
01081
01082 Int_t numeq = TMath::FloorNint(frac*barlen);
01083
01084
01085 nextbar = (Int_t)((Float_t)(numeq+1)/(Float_t)barlen*nEntries);
01086
01087 bar = TString('=', numeq);
01088 bar += TString(' ', barlen - numeq);
01089 } else if (entry > nEntries) {
01090
01091 bar = TString('+', barlen);
01092 } else if (entry < 0) {
01093
01094 bar = TString('-', barlen);
01095 }
01096
01097
01098
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
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
01123 if (entry == nEntries) {
01124 cout << endl;
01125 }
01126 }