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

NCEventInfo.cxx

Go to the documentation of this file.
00001 #include "NCEventInfo.h"
00002 
00003 #include <cassert>
00004 
00005 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00006 #include "AnalysisNtuples/ANtpBeamInfo.h"
00007 #include "AnalysisNtuples/ANtpDefaultValue.h"
00008 #include "AnalysisNtuples/ANtpEventInfo.h"
00009 #include "AnalysisNtuples/ANtpEventInfoNC.h"
00010 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00011 #include "AnalysisNtuples/ANtpRecoInfo.h"
00012 #include "AnalysisNtuples/ANtpShowerInfo.h"
00013 #include "AnalysisNtuples/ANtpShowerInfoNC.h"
00014 #include "AnalysisNtuples/ANtpTrackInfoAtm.h"
00015 #include "AnalysisNtuples/ANtpTrackInfoNC.h"
00016 #include "AnalysisNtuples/ANtpTruthInfo.h"
00017 #include "AnalysisNtuples/ANtpTruthInfoAtm.h"
00018 #include "AnalysisNtuples/ANtpTruthInfoBeam.h"
00019 
00020 #include "Conventions/Detector.h"
00021 #include "Conventions/Munits.h"
00022 
00023 #include "DataUtil/EnergyCorrections.h"
00024 
00025 #include "MCReweight/MCReweight.h"
00026 #include "MCReweight/SKZPWeightCalculator.h"
00027 
00028 #include "MessageService/MsgService.h"
00029 
00030 #include "Validity/VldTimeStamp.h"
00031 #include "Validity/VldContext.h"
00032 
00033 
00034 #include "TChain.h"
00035 #include "TDirectory.h"
00036 #include "TFile.h"
00037 #include "TH2F.h"
00038 #include "TMath.h"
00039 #include "TRandom.h"
00040 #include "TSystem.h"
00041 
00042 #include "NCUtils/NCOscProb.h"
00043 #include "NCUtils/NCType.h"
00044 #include "NCUtils/NCRunUtil.h"
00045 #include "NCUtils/NCUtility.h"
00046 using NC::Utility::SQR;
00047 
00048 using namespace EnergyCorrections;
00049 
00050 CVSID("$Id: NCEventInfo.cxx,v 1.49 2010/01/19 17:02:22 rodriges Exp $");
00051 
00052 static const int kQE = 0;
00053 static const int kRES = 1;
00054 static const int kDIS = 2;
00055 
00056 // define static member
00057 NCEventInfo::INukeHists NCEventInfo::sfINukeHists;
00058 
00059 NCEventInfo::INukeHists::INukeHists()
00060 {
00061   //save the current working directory
00062   TDirectory* tmp = gDirectory;
00063 
00064   //  fCuts = new NCAnalysisCutsNC();
00065   //  fZbeam = new Zbeam();
00066   //  fZfluk = new Zfluk();
00067 
00068   //  fSKZPWeight = new SKZPWeightCalculator(beamWeightConfig,true);
00069   //  fZbeam->SetReweightConfig(beamWeightConfig);
00070 
00071   // ---RPL 05/09/06: instantiate the mcReweight object now, and give
00072   // it a (neugen) weight calculator
00073   // Back this off; Brian says it should be done in the script.
00074   //MCReweight &mcReweight = MCReweight::Instance();
00075   //fNeugenWeightCal = new NeugenWeightCalculator();
00076   //mcReweight.AddWeightCalculator(fNeugenWeightCal);
00077   // ---
00078 
00079   //gotta load shower energy weighting histograms from Mike K.
00080   TString scaleFromName = "integrated_smearing_histos_default.root";
00081   TString scaleToNameMinus = "integrated_smearing_histos_1501.root";
00082   TString scaleToNamePlus = "integrated_smearing_histos_1500.root";
00083   TString offsetName = "integrated_smearing_histos_offset.root";
00084 
00085   TString topDir="MCReweight/data";
00086   TString base=getenv("SRT_PRIVATE_CONTEXT");
00087   if(base!="" && base!="."){
00088     // check if directory exists in SRT_PRIVATE_CONTEXT
00089     TString path = base + "/" + topDir;
00090     void *dir_ptr = gSystem->OpenDirectory(path);
00091     if(!dir_ptr) base=getenv("SRT_PUBLIC_CONTEXT");
00092   }
00093   // if it doesn't exist then use SRT_PUBLIC_CONTEXT
00094   else base=getenv("SRT_PUBLIC_CONTEXT");
00095 
00096   if(base==""){
00097     MSG("NCUtils",Msg::kFatal) << "No SRT_PUBLIC_CONTEXT set" << endl;
00098     assert(false);
00099   }
00100   topDir = base+ "/" + topDir + "/";
00101 
00102   MSG("NCUtils",Msg::kDebug)
00103     << "Zbeam reading files from: " << topDir << endl;
00104   TFile scaleFileFrom(topDir+scaleFromName);
00105   TFile scaleFileToMinus(topDir+scaleToNameMinus);
00106   TFile scaleFileToPlus(topDir+scaleToNamePlus);
00107   TFile offsetFile(topDir+offsetName);
00108 
00109   TString names[] = {"h_qe", "h_res", "h_dis"};
00110 
00111   TH2F *histFrom = dynamic_cast<TH2F *>(scaleFileFrom.Get(names[kQE]));
00112   TH2F *histToMinus = dynamic_cast<TH2F *>(scaleFileToMinus.Get(names[kQE]));
00113   TH2F *histToPlus = dynamic_cast<TH2F *>(scaleFileToPlus.Get(names[kQE]));
00114   TH2F *hist = dynamic_cast<TH2F *>(offsetFile.Get(names[kQE]));
00115 
00116   for(int i = kQE; i < kDIS+1; ++i){
00117 
00118     histFrom = dynamic_cast<TH2F *>(scaleFileFrom.Get(names[i]));
00119     histToMinus = dynamic_cast<TH2F *>(scaleFileToMinus.Get(names[i]));
00120     histToPlus = dynamic_cast<TH2F *>(scaleFileToPlus.Get(names[i]));
00121     hist = dynamic_cast<TH2F *>(offsetFile.Get(names[i]));
00122 
00123     MSG("NCEventInfo", Msg::kDebug)
00124       << histFrom->GetName() << " "
00125       << histToMinus->GetName() << " "
00126       << histToPlus->GetName() << " "
00127       << hist->GetName() << endl;
00128 
00129     from.push_back(histFrom);
00130     toMinus.push_back(histToMinus);
00131     toPlus.push_back(histToPlus);
00132     offset.push_back(hist);
00133 
00134     from[i]->SetDirectory(0);
00135     toMinus[i]->SetDirectory(0);
00136     toPlus[i]->SetDirectory(0);
00137     offset[i]->SetDirectory(0);
00138 
00139     MSG("NCEventInfo", Msg::kDebug)
00140       << from[i]->GetName() << " "
00141       << toMinus[i]->GetName() << " "
00142       << toPlus[i]->GetName() << " "
00143       << offset[i]->GetName() << endl;
00144 
00145   }//end loop to fill histograms
00146 
00147   gDirectory = tmp;
00148 }
00149 
00150 //---------------------------------------------------------------------
00151 NCEventInfo::INukeHists::~INukeHists()
00152 {
00153   for(unsigned int n = 0; n < offset.size(); ++n) delete offset[n];
00154   for(unsigned int n = 0; n < from.size(); ++n) delete from[n];
00155   for(unsigned int n = 0; n < toMinus.size(); ++n) delete toMinus[n];
00156   for(unsigned int n = 0; n < toPlus.size(); ++n) delete toPlus[n];
00157 }
00158 
00159 //---------------------------------------------------------------------
00160 NCEventInfo::NCEventInfo(const char* beamWeightConfig)
00161   : analysis(0), beam(0), event(0), header(0),
00162     reco_nom(0), reco(0), shower(0), track(0), truth(0),
00163     fSKZPWeight(0),
00164     fBeamWeightConfig(beamWeightConfig)
00165 {
00166 }
00167 
00168 //---------------------------------------------------------------------
00169 SKZPWeightCalculator* NCEventInfo::GetSKZPCalc()
00170 {
00171   if(!fSKZPWeight)
00172     fSKZPWeight = new SKZPWeightCalculator(fBeamWeightConfig, true);
00173 
00174   const ReleaseType::Release_t rel
00175     = ReleaseType::StringToType(header->softVersion);
00176 
00177   if(fBeamWeightConfig == "PiMinus_CedarDaikon"){
00178     if(!ReleaseType::IsCedar(rel)){
00179       MAXMSG("NCEventInfo", Msg::kError, 10) << endl
00180         << "*******************************************************" << endl
00181         << "* APPLYING CEDARDAIKON SKZP TO NON CEDAR FILE         *" << endl
00182         << "* FIX BEFORE YOU DO A REAL ANALYSIS.                  *" << endl
00183         << "*******************************************************" << endl;
00184     }
00185     if(ReleaseType::IsMC(rel) && !ReleaseType::IsDogwood(rel)){
00186       MAXMSG("NCEventInfo", Msg::kError, 10) << endl
00187         << "*******************************************************" << endl
00188         << "* APPLYING CEDARDAIKON SKZP TO NON DOGWOOD FILE       *" << endl
00189         << "* FIX BEFORE YOU DO A REAL ANALYSIS.                  *" << endl
00190         << "*******************************************************" << endl;
00191     }
00192   }
00193 
00194   if(fBeamWeightConfig == "Dogwood1_Daikon07" && !ReleaseType::IsDogwood(rel)){
00195     MAXMSG("NCEventInfo", Msg::kError, 10) << endl
00196       << "*******************************************************" << endl
00197       << "* APPLYING DOGWOODDAIKON07 SKZP TO NON DOGWOOD FILE   *" << endl
00198       << "* FIX BEFORE YOU DO A REAL ANALYSIS.                  *" << endl
00199       << "*******************************************************" << endl;
00200   }
00201   
00202 
00203   return fSKZPWeight;
00204 }
00205 
00206 //---------------------------------------------------------------------
00207 void NCEventInfo::DeepCopy(const NCEventInfo* evt)
00208 {
00209 #define COPYFIELD(fld, typ) \
00210   if(evt->fld){             \
00211     if(!fld) fld = new typ; \
00212     *fld = *evt->fld;       \
00213   }                         \
00214   else{                     \
00215     if(fld) delete fld;     \
00216     fld = 0;                \
00217   }
00218 
00219   COPYFIELD(analysis, ANtpAnalysisInfo);
00220   COPYFIELD(beam,     ANtpBeamInfo);
00221   COPYFIELD(event,    ANtpEventInfoNC);
00222   COPYFIELD(header,   ANtpHeaderInfo);
00223   COPYFIELD(reco,     ANtpRecoInfo);
00224   COPYFIELD(reco_nom, ANtpRecoInfo);
00225   COPYFIELD(shower,   ANtpShowerInfoNC);
00226   COPYFIELD(track,    ANtpTrackInfoNC);
00227   COPYFIELD(truth,    ANtpTruthInfoBeam);
00228 
00229 #undef COPYFIELD
00230 }
00231 
00232 //---------------------------------------------------------------------
00233 double NCEventInfo::GetEventVertex(double& x, double& y, double& z) const
00234 {
00235   // choice of whether to use Event or Track vertex should follow what is in
00236   //NCAnalysisCuts::InBeamFiducialVolumeOx(), otherwise the vertex that is being
00237   //cut and the vertex that is being stored are not the same
00238 
00239   assert(header);
00240   assert(event && track && shower);
00241 
00242   // If we have reco_nom then it's analysis time and we shouldn't
00243   // be redoing the calculation but merely using the variables we
00244   // calculated before.
00245   assert(!reco_nom);
00246 
00247   if(event->tracks > 0 &&
00248      track->planes - shower->planes > 0){
00249     x = track->vtxX;
00250     y = track->vtxY;
00251     z = track->vtxZ  - NCType::kTrackVtxAdjustment;
00252   }
00253   else{
00254     x = event->vtxX;
00255     y = event->vtxY;
00256     z = event->vtxZ;
00257   }
00258 
00259   // Correct the coordinates into beam coordinates for the purposes of
00260   // calculating this return value only.
00261   if(header->detector == int(Detector::kNear)){
00262     const double x1 = x - NCType::kNDBeamCenterX;
00263     const double y1 = y - NCType::kNDBeamCenterY - NCType::kNDBeamAngle*z;
00264     return TMath::Sqrt(x1*x1 + y1*y1);
00265   }
00266 
00267   return TMath::Sqrt(x*x + y*y);
00268 }
00269 
00270 
00271 //---------------------------------------------------------------------
00272 double NCEventInfo::GetEventEnergy(CandShowerHandle::ShowerType_t showerType,
00273                                    bool stoppingBeamMuon) const
00274 {
00275   double showerEnergy = 0.;
00276   double trackEnergy = 0.;
00277 
00278   if(event->showers > 0)
00279     showerEnergy = GetShowerEnergy(showerType);
00280   if(event->tracks > 0)
00281     trackEnergy = GetTrackEnergy(stoppingBeamMuon);//fCuts->IsStoppingBeamMuon());
00282 
00283 
00284   if(showerType == CandShowerHandle::kWtNC) return showerEnergy;
00285 
00286   return trackEnergy + showerEnergy;
00287 }
00288 
00289 
00290 //---------------------------------------------------------------------
00291 double NCEventInfo::GetTrackEnergy(bool contained) const
00292 {
00293   assert(header);
00294 
00295   const SimFlag::SimFlag_t sim = SimFlag::SimFlag_t(header->dataType);
00296 
00297   using namespace ReleaseType;
00298   const Release_t rt = StringToType(header->softVersion);
00299 
00300   const Detector::Detector_t det = Detector::Detector_t(header->detector);
00301 
00302   //get a validity context for the energy corrections
00303   VldContext vldc(det, sim, GetTimestamp());
00304 
00305   bool fromCurve = false;
00306   bool fromRange = false;
00307 
00308   double inputMomentum;
00309 
00310   if(contained || track->fitMomentum < -9000) {
00311     if(track->rangeMomentum > 0){
00312       fromRange = true;
00313       inputMomentum = track->rangeMomentum;
00314     }
00315     else{
00316       fromCurve = true;
00317       inputMomentum = track->fitMomentum;
00318     }
00319   }
00320   else{
00321     fromCurve = true;
00322     inputMomentum = track->fitMomentum;
00323   }
00324 
00325   assert(fromCurve || fromRange);
00326   assert(!(fromCurve && fromRange));
00327 
00328   // required to shut gcc up in optimized mode
00329   // the asserts above guarantee that one of the branches below will be taken
00330   double trackMomentum = 0;
00331 
00332   if(fromCurve)
00333     trackMomentum = FullyCorrectSignedMomentumFromCurvature(inputMomentum,
00334                                                             vldc, rt);
00335   if(fromRange)
00336     trackMomentum = FullyCorrectMomentumFromRange(inputMomentum, vldc, rt);
00337 
00338   return TMath::Sqrt(SQR(trackMomentum) + SQR(NCType::kMuMassGeV));
00339 }
00340 
00341 //---------------------------------------------------------------------
00342 double NCEventInfo::doubleintpow(double a, int b) const
00343 {
00344   double ret = 1;
00345   while(b--) ret *= a;
00346   return ret;
00347 }
00348 
00349 //---------------------------------------------------------------------
00350 
00351 double NCEventInfo::MasakiStyleCorrectionImp(double logE, const double pars[6]) const
00352 {
00353   // logE is log_10(shower energy)
00354   // pars are the Chebyshev coefficients
00355   double ret = 2.-(pars[0]+
00356                    pars[1]*logE+
00357                    pars[2]*(2.*doubleintpow(logE, 2)-1.)+
00358                    pars[3]*(4.*doubleintpow(logE, 3)-3.*logE)+
00359                    pars[4]*(8.*doubleintpow(logE, 4)-8.*doubleintpow(logE, 2)+1.)+
00360                    pars[5]*(16.*doubleintpow(logE, 5)-
00361                             20.*doubleintpow(logE, 3)+5.*logE));
00362   ret = min(ret, 1.3);
00363   ret = max(ret, 0.7);
00364   return ret;
00365 }
00366 
00367 //---------------------------------------------------------------------
00368 double NCEventInfo::MasakiStyleCorrectionCedarPhyLinfix(double E) const
00369 {
00370   // Masaki-style energy corrections appropriate for the
00371   // cedar_phy_linfix sample. See docdb 5753
00372 
00373   const ReleaseType::Release_t rel
00374     = ReleaseType::StringToType(header->softVersion);
00375   if(!ReleaseType::IsCedar(rel)){
00376     MAXMSG("NCEventInfo", Msg::kError, 10) << endl
00377       << "***********************************************************" << endl
00378       << "* APPLYING CEDAR-PHY ENERGY CORRECTIONS TO NON CEDAR FILE *" << endl
00379       << "* FIX BEFORE YOU DO A REAL ANALYSIS.                      *" << endl
00380       << "***********************************************************" << endl;
00381   }
00382   if(ReleaseType::IsMC(rel) && !ReleaseType::IsDogwood(rel)){
00383     MAXMSG("NCEventInfo", Msg::kError, 10) << endl
00384       << "***********************************************************" << endl
00385       << "* APPLYING ENERGY CORRECTIONS TO NON DOGWOOD FILE         *" << endl
00386       << "* FIX BEFORE YOU DO A REAL ANALYSIS.                      *" << endl
00387       << "***********************************************************" << endl;
00388   }
00389 
00390   if(E==0) return 1.;
00391 
00392   E=max(E, 0.2);
00393 
00394   // Different corrections for near/far, low/high energy (E<>10 GeV)
00395 
00396   const double parsNDLo[6]={ 8.78922e-01,  2.01774e-01, -1.91411e-01,
00397                              1.45199e-01, -1.02706e-01 , 3.67004e-02 };
00398   const double parsNDHi[6]={ 1.02466,      2.76558e-01, -6.60202e-01,
00399                              4.36941e-01, -1.21538e-01,  0.0120561   };
00400   const double parsFDLo[6]={ 8.49032e-01,  2.81519e-01, -2.48210e-01,
00401                              1.73536e-01, -9.64045e-02,  3.11845e-02 };
00402   const double parsFDHi[6]={ 9.66207e-01,  3.04379e-01, -5.45190e-01,
00403                              3.49389e-01, -9.28317e-02,  0.00870293  };
00404 
00405   const double* parsToUse;
00406 
00407   if(header->detector == (int)Detector::kNear)
00408     parsToUse= (E<=10) ? parsNDLo : parsNDHi;
00409   else if(header->detector == (int)Detector::kFar)
00410     parsToUse= (E<=10) ? parsFDLo : parsFDHi;
00411   else assert (0 && "DISASTER!!!!!! Unknown detector");
00412 
00413   return MasakiStyleCorrectionImp(log10(E), parsToUse);
00414 }
00415 
00416 //---------------------------------------------------------------------
00417 double NCEventInfo::
00418 GetShowerEnergy(CandShowerHandle::ShowerType_t showerType) const
00419 {
00420   assert(header);
00421   assert(shower);
00422 
00423   // If we have reco_nom then it's analysis time and we shouldn't
00424   // be redoing the calculation but merely using the variables we
00425   // calculated before.
00426   assert(!reco_nom);
00427 
00428   const SimFlag::SimFlag_t sim = SimFlag::SimFlag_t(header->dataType);
00429 
00430   using namespace ReleaseType;
00431   const Release_t rt = StringToType(header->softVersion);
00432 
00433   const Detector::Detector_t det = Detector::Detector_t(header->detector);
00434 
00435   //get a validity context for the energy corrections
00436   VldContext vldc(det, sim, GetTimestamp());
00437 
00438   double showerEnergy = ANtpDefaultValue::kDouble;
00439 
00440   switch(showerType){
00441   case CandShowerHandle::kCC:
00442     showerEnergy = shower->linearCCGeV;
00443     break;
00444   case CandShowerHandle::kWtCC:
00445     showerEnergy = shower->deweightCCGeV;
00446     break;
00447   case CandShowerHandle::kNC:
00448     showerEnergy = shower->linearNCGeV;
00449     break;
00450   case CandShowerHandle::kWtNC:
00451     showerEnergy = shower->deweightNCGeV;
00452     break;
00453   case CandShowerHandle::kEM:
00454     assert(0 && "Not implemented");
00455   }
00456 
00457   if(showerEnergy > 0){
00458     showerEnergy = FullyCorrectShowerEnergy(showerEnergy,
00459                                             showerType, vldc, rt);
00460 
00461     // Do post-hoc MEU corrections for cedar_phy_linfix MC. Taken from
00462     // docdb 5340 for the ND, and an email I have from Alex (forwarded
00463     // from Greg) for the FD
00464     //
00465     // These constants are only for cedar_phy_linfix, but there's no way
00466     // to tell that from the release type so cedar is the best we can test for
00467     if(sim == SimFlag::kMC && ReleaseType::IsCedar(rt)){
00468       if(det == Detector::kNear)     showerEnergy *= 1.007667;
00469       else if(det == Detector::kFar) showerEnergy *= 1.0018;
00470       else MSG("NCEventInfo", Msg::kWarning) << "Don't know detector: "
00471                                              << det << endl;
00472     }//MC
00473 
00474     // Only apply the Masaki-style corrections to CC showers
00475     if(showerType != CandShowerHandle::kCC) return showerEnergy;
00476     return (showerEnergy*MasakiStyleCorrectionCedarPhyLinfix(showerEnergy));
00477   }
00478 
00479   return showerEnergy;
00480 }
00481 
00482 
00483 //---------------------------------------------------------------------------
00484 //will find MODBYRS3 weight for MC version carrot or earlier even when all
00485 //values of useParameters are set to false.
00486 double NCEventInfo::FindNeugenWeight(const bool* useParameters,
00487                                      const std::vector<double>& adjustedValues,
00488                                      bool useMODBYRS3, int overrideMODBYRS)
00489 {
00490   assert(truth);
00491 
00492   TString neugen = "neugen:";
00493 
00494   MCReweight &mcReweight = MCReweight::Instance();
00495 
00496   int nucleus = 1; //default
00497 
00498   //figure out the nucleus
00499   if(int(truth->atomicNumber == 1))  nucleus = 0; // free
00500   else if(int(truth->atomicNumber == 6))  nucleus = 274; // oxygen
00501   else if(int(truth->atomicNumber == 8))  nucleus = 284; // carbon
00502   else if(int(truth->atomicNumber == 26)) nucleus = 372; // iron
00503 
00504   if(nucleus == 1) return 1;
00505 
00506   MCEventInfo ei;
00507   ei.nuE           = truth->nuEnergy;
00508   ei.nuPx          = truth->nuDCosX*truth->nuEnergy;
00509   ei.nuPy          = truth->nuDCosY*truth->nuEnergy;
00510   ei.nuPz          = truth->nuDCosZ*truth->nuEnergy;
00511   ei.tarE          = truth->targetEnergy;
00512   ei.tarPx         = truth->targetPX;
00513   ei.tarPy         = truth->targetPY;
00514   ei.tarPz         = truth->targetPZ;
00515   ei.y             = truth->hadronicY;
00516   ei.x             = truth->bjorkenX;
00517   ei.q2            = truth->q2;
00518   ei.w2            = truth->w2;
00519   ei.iaction       = truth->interactionType;
00520   ei.inu           = truth->nuFlavor;
00521   ei.iresonance    = truth->resonanceCode;
00522   ei.initial_state = truth->initialState;
00523   ei.nucleus       = nucleus;
00524   ei.had_fs        = truth->hadronicFinalState;
00525 
00526   NuParent* np = 0;
00527 
00528   Registry fReweightConfigRegistry;
00529   fReweightConfigRegistry.UnLockValues();
00530   Registry defaultConfigRegistry;
00531 
00532   const char* mcString = (header->softVersion).Data();
00533   ReleaseType::Release_t mcType=ReleaseType::StringToType(mcString);
00534 
00535 
00536   //Only apply MODBYRS3 for Carrot or earlier
00537   //Note: According to discussion with Hugh G. and
00538   //Tricia V., Carrot was actually generated with MODBYRS2
00539   //and then found to agree better with data using MODBYRS3.
00540   //Anyone using this code on carrot will get unweighted carrot if
00541   //useMODBYRS3=false and reweighted carrot if flag useMODBYRS3=true
00542 
00543   //overriding default version values for MODBYRS
00544   if(overrideMODBYRS != 0)
00545   {
00546      fReweightConfigRegistry.Set("neugen:config_name", "MODBYRS");
00547      fReweightConfigRegistry.Set("neugen:config_no", overrideMODBYRS);
00548   }
00549   //no override
00550   else
00551   {
00552      if(useMODBYRS3 && ReleaseType::IsCarrot(mcType) ){
00553         fReweightConfigRegistry.Set("neugen:config_name", "MODBYRS");
00554         fReweightConfigRegistry.Set("neugen:config_no", 3);
00555      }
00556      else if(ReleaseType::IsDaikon(mcType)){
00557         fReweightConfigRegistry.Set("neugen:config_name", "MODBYRS");
00558         fReweightConfigRegistry.Set("neugen:config_no", 4);
00559      }
00560   }
00561   /*
00562   if((int) useParameters.size() < NCType::kNumNeugenParameters){
00563     MSG("NCEventInfo", Msg::kWarning) << "use parameters not same size"
00564                                           << " as neugen parameters - return"
00565                                           << " weight of 1." << endl;
00566     return 1.;
00567   }
00568   */
00569 
00570   //set the configuration for the reweight based on the percent change
00571   double change = 1.;
00572   for(int i = 0; i < (int)adjustedValues.size(); ++i){
00573     change = adjustedValues[i];
00574 
00575     //for now the reweighting doesnt work right - see comment below
00576     //make sure that the defaults for all unchanged parameters are the
00577     //current defaults
00578     if(!useParameters[i]
00579        && i < NCType::kDISFACT
00580        && !(i == NCType::kma_qe && useParameters[NCType::kCCMA])
00581        && !(i == NCType::kma_res && useParameters[NCType::kCCMA])
00582        && !(i == NCType::kkno_r112 && useParameters[NCType::kkno_r112122])
00583        && !(i == NCType::kkno_r122 && useParameters[NCType::kkno_r112122])
00584        && !(i == NCType::kkno_r113 && useParameters[NCType::kkno_r113123])
00585        && !(i == NCType::kkno_r123 && useParameters[NCType::kkno_r113123])
00586        && !(i == NCType::kkno_r212 && useParameters[NCType::kkno_r212222])
00587        && !(i == NCType::kkno_r222 && useParameters[NCType::kkno_r212222])
00588        && !(i == NCType::kkno_r213 && useParameters[NCType::kkno_r213223])
00589        && !(i == NCType::kkno_r223 && useParameters[NCType::kkno_r213223])) {
00590 
00591        if(ReleaseType::IsDaikon(mcType))
00592        {
00593           fReweightConfigRegistry.Set(neugen+NCType::kParams[i].name,
00594                                       NCType::kParams[i].defaultVal);
00595        }
00596     }
00597 
00598     if(useParameters[i] && i < NCType::kDISFACT){
00599       fReweightConfigRegistry.Set(neugen+NCType::kParams[i].name, change);
00600     }
00601     else if(useParameters[i] && i == NCType::kDISFACT){
00602       //here adjusted values is the fractional change for the parameters,
00603       //multiply it by the default values
00604       fReweightConfigRegistry.Set("neugen:kno_r112",
00605                                   change*NCType::kParams[NCType::kkno_r112].defaultVal);
00606       fReweightConfigRegistry.Set("neugen:kno_r122",
00607                                   change*NCType::kParams[NCType::kkno_r122].defaultVal);
00608       fReweightConfigRegistry.Set("neugen:kno_r132",
00609                                   change*NCType::kParams[NCType::kkno_r132].defaultVal);
00610       fReweightConfigRegistry.Set("neugen:kno_r142",
00611                                   change*NCType::kParams[NCType::kkno_r142].defaultVal);
00612       fReweightConfigRegistry.Set("neugen:kno_r113",
00613                                   change*NCType::kParams[NCType::kkno_r113].defaultVal);
00614       fReweightConfigRegistry.Set("neugen:kno_r123",
00615                                   change*NCType::kParams[NCType::kkno_r123].defaultVal);
00616       fReweightConfigRegistry.Set("neugen:kno_r133",
00617                                   change*NCType::kParams[NCType::kkno_r133].defaultVal);
00618       fReweightConfigRegistry.Set("neugen:kno_r143",
00619                                   change*NCType::kParams[NCType::kkno_r143].defaultVal);
00620     }
00621     else if(useParameters[i] && i == NCType::kCCMA){
00622       fReweightConfigRegistry.Set("neugen:ma_qe",
00623                                   change*NCType::kParams[NCType::kma_qe].defaultVal);
00624       fReweightConfigRegistry.Set("neugen:ma_res",
00625                                   change*NCType::kParams[NCType::kma_res].defaultVal);
00626     }
00627     else if(useParameters[i] && i == NCType::kkno_r112122){
00628       fReweightConfigRegistry.Set("neugen:kno_r112",
00629                                   change*NCType::kParams[NCType::kkno_r112].defaultVal);
00630       fReweightConfigRegistry.Set("neugen:kno_r122",
00631                                   change*NCType::kParams[NCType::kkno_r122].defaultVal);
00632     }
00633     else if(useParameters[i] && i == NCType::kkno_r113123){
00634       fReweightConfigRegistry.Set("neugen:kno_r113",
00635                                   change*NCType::kParams[NCType::kkno_r113].defaultVal);
00636       fReweightConfigRegistry.Set("neugen:kno_r123",
00637                                   change*NCType::kParams[NCType::kkno_r123].defaultVal);
00638     }
00639     else if(useParameters[i] && i == NCType::kkno_r212222){
00640       fReweightConfigRegistry.Set("neugen:kno_r212",
00641                                   change*NCType::kParams[NCType::kkno_r212].defaultVal);
00642       fReweightConfigRegistry.Set("neugen:kno_r222",
00643                                   change*NCType::kParams[NCType::kkno_r222].defaultVal);
00644     }
00645     else if(useParameters[i] && i == NCType::kkno_r213223){
00646       fReweightConfigRegistry.Set("neugen:kno_r213",
00647                                   change*NCType::kParams[NCType::kkno_r213].defaultVal);
00648       fReweightConfigRegistry.Set("neugen:kno_r223",
00649                                   change*NCType::kParams[NCType::kkno_r223].defaultVal);
00650     }
00651 
00652   }//end loop over adjusted values
00653 
00654   mcReweight.ResetAllReweightConfigs();
00655 
00656   double weight = mcReweight.ComputeWeight(&ei,np,&fReweightConfigRegistry);
00657 
00658   //reweighting is in strange state right now - it returns the weight
00659   //with respect to parameters as of MODBYRS2 - Daikon is MODBYRS4
00660   //so have to get weight from MODBYRS2 defaults to MODBYRS4 defaults first
00661   double defaultWeight = 1.;
00662   if(ReleaseType::IsDaikon(mcType)){
00663     defaultConfigRegistry.Set("neugen:config_name", "MODBYRS");
00664     defaultConfigRegistry.Set("neugen:config_no", 4);
00665 
00666     //use defaults for all parameters up to the combinations
00667     for(int i = 0; i < NCType::kDISFACT; ++i)
00668       defaultConfigRegistry.Set(neugen+NCType::kParams[i].name,
00669                                 NCType::kParams[i].defaultVal);
00670 
00671     mcReweight.ResetAllReweightConfigs();
00672 
00673     defaultWeight = mcReweight.ComputeWeight(&ei,np,&defaultConfigRegistry);
00674 
00675   }//end if daikon
00676 
00677   //divide reweight by default weight
00678   //cout << "oldw = " << weight << endl;
00679   if(TMath::Abs(defaultWeight) > 0.) weight /= defaultWeight;
00680   //cout << "neww = " << weight << endl;
00681   //cout << "neww*w = " << weight * reco->weight << endl;
00682   if( TMath::IsNaN(weight) ){
00683     MSG("NCEventInfo", Msg::kWarning)
00684       << "mcreweight IsNaN "
00685       <<  truth->nuEnergy
00686       << " " << truth->interactionType
00687       << " " << truth->resonanceCode
00688       << " " << truth->nuFlavor
00689       << " " << truth->initialState
00690       << " " << truth->hadronicFinalState
00691       << " " << nucleus
00692       << endl;
00693     weight = 1.;
00694   }
00695 
00696   if(weight != 1.){
00697     MAXMSG("NCEventInfo", Msg::kDebug, 100)
00698       << "mcreweight to " << weight << endl
00699       << "values into neugen" << endl
00700       << "event:nu_en "
00701       << truth->nuEnergy << endl
00702       << "event:nu_px "
00703       << truth->nuDCosX*truth->nuEnergy << endl
00704       << "event:nu_py "
00705       << truth->nuDCosY*truth->nuEnergy << endl
00706       << "event:nu_pz "
00707       << truth->nuDCosZ*truth->nuEnergy << endl
00708       << "event:tar_en "
00709       << truth->targetEnergy << endl
00710       << "event:tar_px "
00711       << truth->targetPX << endl
00712       << "event:tar_py "
00713       << truth->targetPY << endl
00714       << "event:tar_pz "
00715       << truth->targetPZ << endl
00716       << "event:x "
00717       << truth->bjorkenX << endl
00718       << "event:y "
00719       << truth->hadronicY << endl
00720       << "event:q2 " << truth->q2 << endl
00721       << "event:w2 " << truth->w2 << endl
00722       << "event:iaction "
00723       << truth->interactionType << endl
00724       << "event:inu "
00725       << truth->nuFlavor << endl
00726       << "event:iresonance "
00727       << truth->resonanceCode << endl
00728       << "event:initial_state "
00729       << truth->initialState << endl
00730       << "event:nucleus " << nucleus << endl
00731       << "event:had_fs "
00732       << truth->hadronicFinalState
00733       << endl << endl;
00734   }
00735 
00736   return weight;
00737 }
00738 
00739 
00740 //---------------------------------------------------------------------------
00741 double NCEventInfo::FindCrossSectionWeight(const bool* useParameters,
00742                                            const std::vector<double>& adjustedValues) const
00743 {
00744   double weight = 1.;
00745   double trueE = truth->nuEnergy;
00746 
00747   if(useParameters[NCType::kNCCrossSection]
00748      && truth->interactionType == NCType::kNC){
00749     if(trueE <= 10.)
00750       weight = 1. + 0.2*adjustedValues[NCType::kNCCrossSection];
00751     else if(trueE < 100.)
00752       weight = 1. + 0.2*(1. - 0.0111*(trueE-10.))*adjustedValues[NCType::kNCCrossSection];
00753     else
00754       weight = 1.;
00755   }
00756 
00757   if(useParameters[NCType::kNuBarCrossSection]
00758      && truth->interactionType == NCType::kCC
00759      && truth->nuFlavor < 0)
00760     weight *= 1. + adjustedValues[NCType::kNuBarCrossSection];
00761 
00762   return weight;
00763 }
00764 
00765 
00766 //----------------------------------------------------------------------
00767 //calls FindNeugenWeight without any parameters set to true.  FindNeugenWeight
00768 //returns the MODBYRS3 weight in that case if the release is carrot or
00769 //earlier, otherwise returns 1.
00770 double NCEventInfo::FindMODBYRSWeight()
00771 {
00772   vector<double> adjustedValues;
00773   bool useParameters[NCType::kNumNeugenParameters] = {false,};
00774 
00775   for(int i = 0; i < NCType::kNumNeugenParameters; ++i){
00776     adjustedValues.push_back(NCType::kParams[i].defaultVal);
00777   }
00778 
00779   return FindNeugenWeight(useParameters, adjustedValues);
00780 }
00781 
00782 
00783 //---------------------------------------------------------------------------
00784 //this version of the method uses the shiny new functionality
00785 //in MCReweight to get the #'s from the db
00786 double NCEventInfo::FindMEGAFitWeight(int beamType, NC::RunUtil::ERunType runType)
00787 {
00788   //check if there is a beam object loaded, if so use it to get the beam type,
00789   //otherwise use the passed in int.
00790   int beamt = BeamType::ToZarko((BeamType::BeamType_t)(beamType)); //Use SKZP beam encoding
00791   if(beam) beamt = BeamType::ToZarko((BeamType::BeamType_t)(beam->beamType)); //Use SKZP beam encoding
00792 
00793   SKZPWeightCalculator::RunPeriod_t rp;
00794 
00795   // Bah, converting between conventions
00796   switch(runType){
00797   case NC::RunUtil::kRunI:
00798     rp=SKZPWeightCalculator::kRunI;
00799     break;
00800   case NC::RunUtil::kRunII:
00801     rp=SKZPWeightCalculator::kRunII;
00802     break;
00803   case NC::RunUtil::kRunIII:
00804     rp=SKZPWeightCalculator::kRunIII;
00805     break;
00806   default:
00807     assert(0 && "Unknown run period");
00808     break;
00809   }
00810 
00811   double pt = TMath::Sqrt(SQR(truth->targetParentPX)
00812                           +SQR(truth->targetParentPY));
00813   double emuNew = 0.;
00814   double eshwNew = 0.;
00815   double beamweight = 0.;
00816   double detweight = 0.;
00817   double weightbeam = GetSKZPCalc()->GetWeight(header->detector,
00818                                                beamt,
00819                                                truth->targetParentType,
00820                                                pt,
00821                                                1.*truth->targetParentPZ,
00822                                                truth->interactionType,
00823                                                truth->nuEnergy,
00824                                                truth->nuFlavor,
00825                                                0.,
00826                                                0.,
00827                                                emuNew,
00828                                                eshwNew,
00829                                                beamweight,
00830                                                detweight,
00831                                                rp);
00832 
00833   //only do the MODBYRS weighting if using carrot
00834   double weightMODBYRS = 1.;
00835   const char* mcString = (header->softVersion).Data();
00836   ReleaseType::Release_t mcType = ReleaseType::StringToType(mcString);
00837   if( ReleaseType::IsCarrot(mcType) ) weightMODBYRS = FindMODBYRSWeight();
00838 
00839   MAXMSG("NCEventInfo", Msg::kDebug, 10)
00840     << "MODBYRS3 = " << weightMODBYRS
00841     << " beam = " << weightbeam
00842     << endl;
00843 
00844   return weightMODBYRS*weightbeam;
00845 }
00846 
00847 
00848 //---------------------------------------------------------------------------
00849 double NCEventInfo::FindMEGAFitWeightUncertainty(int beamType,
00850                                                  NC::RunUtil::ERunType runType,
00851                                                  double sigma,
00852                                                  SKZPWeightCalculator* skzpcalc)
00853 {
00854   assert(header && truth);
00855 
00856   SKZPWeightCalculator::RunPeriod_t rp = SKZPWeightCalculator::kRunI;
00857   if(runType == NC::RunUtil::kRunII) rp = SKZPWeightCalculator::kRunII;
00858 
00859   return skzpcalc->GetFluxError(header->detector,
00860                                 BeamType::ToZarko((BeamType::BeamType_t)(beamType)), //use SKZP enum
00861                                 truth->nuFlavor,
00862                                 truth->nuEnergy,
00863                                 SKZPWeightCalculator::kTotalErrorAfterTune,
00864                                 sigma);
00865 }
00866 
00867 
00868 //---------------------------------------------------------------------------
00869 double NCEventInfo::
00870 CalculateAbsoluteHadronicShiftScale(double trueShowerEnergy,
00871                                     double sigma) const
00872 {
00873   const double calibrationError = 5.7;
00874 
00875   assert(trueShowerEnergy >= 0);
00876 
00877   double modellingError = -1;
00878   if(trueShowerEnergy < 0.5) modellingError = 8.2;
00879   else if(trueShowerEnergy < 10) modellingError = 2.7+3.7*TMath::Exp(-.25*trueShowerEnergy);
00880   else modellingError = 3;
00881   assert(modellingError > 0);
00882 
00883   const double totalError = TMath::Sqrt(SQR(calibrationError)+
00884                                         SQR(modellingError));
00885   return 1+.01*totalError*sigma;
00886 }
00887 
00888 
00889 //---------------------------------------------------------------------------
00890 
00891 void NCEventInfo::ShiftEnergies(const bool* useParameters,
00892                                 const vector<double>& adjustedValues)
00893 {
00894   assert(analysis);
00895   assert(reco_nom);
00896   //  assert(useParameters.size() == adjustedValues.size());
00897 
00898   // Reset the energies in the reco object to their versions in
00899   // reco_nom to ensure that this function is idempotent
00900   reco->muEnergy=reco_nom->muEnergy;
00901   reco->showerEnergyNC=reco_nom->showerEnergyNC;
00902   reco->showerEnergyCC=reco_nom->showerEnergyCC;
00903   reco->nuEnergyNC=reco_nom->nuEnergyNC;
00904   reco->nuEnergyCC=reco_nom->nuEnergyCC;
00905 
00906   const double trackEnergy_nom=reco_nom->muEnergy;
00907 
00908   if(TMath::Abs(trackEnergy_nom) > NCType::kMuMassGeV){
00909     double trackMomentum = TMath::Sqrt(SQR(trackEnergy_nom) - SQR(NCType::kMuMassGeV));
00910 
00911     if(useParameters[NCType::kTrackEnergy])
00912       trackMomentum *= 1. + adjustedValues[NCType::kTrackEnergy];
00913 
00914     reco->muEnergy = TMath::Sqrt(SQR(trackMomentum) + SQR(NCType::kMuMassGeV));
00915   }
00916 
00917   double showerEnergyNC_nom = reco_nom->showerEnergyNC;
00918   double showerEnergyCC_nom = reco_nom->showerEnergyCC;
00919 
00920   // Only try to shift the shower if there is one
00921   if(! (ANtpDefaultValue::IsDefault(showerEnergyNC_nom) &&
00922         ANtpDefaultValue::IsDefault(showerEnergyCC_nom)) ){
00923     //old way of doing it by scaling shower energy
00924     if(useParameters[NCType::kShowerEnergy] &&
00925        !useParameters[NCType::kAbsoluteHadronicCalibration]) {
00926       const double scale= 1. + adjustedValues[NCType::kShowerEnergy];
00927 
00928       reco->showerEnergyNC*=scale;
00929       reco->showerEnergyCC*=scale;
00930     }
00931 
00932     if(useParameters[NCType::kAbsoluteHadronicCalibration]){
00933       const double trueShowerEnergy = truth->showerEnergy;
00934       const double sigma = adjustedValues[NCType::kAbsoluteHadronicCalibration];
00935       const double scale = CalculateAbsoluteHadronicShiftScale(trueShowerEnergy, sigma);
00936       reco->showerEnergyNC *= scale;
00937       reco->showerEnergyCC *= scale;
00938     }
00939 
00940     if(useParameters[NCType::kRelativeHadronicCalibration] &&
00941        header->detector == Detector::kFar){
00942       const double scale= 1. + adjustedValues[NCType::kRelativeHadronicCalibration];
00943       
00944       reco->showerEnergyNC *= scale;
00945       reco->showerEnergyCC *= scale;
00946     }
00947     assert(reco->showerEnergyNC >= 0);
00948     assert(reco->showerEnergyCC >= 0);
00949   }
00950 
00951   //new way using mike's histograms
00952 
00953   int offset = kQE;
00954   int from = kQE;
00955   int to = kQE;
00956   SelectINukeHist(offset, from, to);
00957 
00958   // if(useParameters[1] && adjustedValues[1] < 0.)
00959   //   showerEnergy = ReweightInuke(fINukeFrom[from], fINukeToMinus[to]);
00960   // else if(useParameters[1] && adjustedValues[1] > 0.)
00961   //   showerEnergy = ReweightInuke(fINukeFrom[from], fINukeToPlus[to]);
00962 
00963   //Shower offset must be greater than 0 to use.
00964   if(useParameters[NCType::kShowerEnergyOffset]
00965      && TMath::Abs(adjustedValues[NCType::kShowerEnergyOffset])>0.0)
00966     // This is wrong, but will make it compile. If you get here,
00967     // SimulateShowerOffset will abort anyway
00968     reco->showerEnergyNC  = SimulateShowerOffset(sfINukeHists.offset[offset],
00969                                                  adjustedValues[NCType::kShowerEnergyOffset]);
00970 
00971   reco->nuEnergyNC = reco->showerEnergyNC;
00972   reco->nuEnergyCC = reco->muEnergy + reco->showerEnergyCC;
00973 
00974   if(analysis->isNC>0){ 
00975     reco->showerEnergy=reco->showerEnergyNC;
00976     reco->nuEnergy=reco->nuEnergyNC;
00977   }
00978 
00979   if(analysis->isCC>0){ 
00980     reco->showerEnergy=reco->showerEnergyCC;
00981     reco->nuEnergy=reco->nuEnergyCC;
00982   }
00983 }
00984 
00985 //---------------------------------------------------------------------------
00986 
00987 double NCEventInfo::FindRecoWeight(const bool* useParameters,
00988                                    const vector<double>& adjustedValues) const
00989 {
00990   double weight = 1;
00991 
00992   const double showerEnergyNC=reco->showerEnergyNC;
00993 
00994   //adjust the weight for the event based on the parameters to fit
00995   if(useParameters[NCType::kNormalization]
00996      && header->dataType==SimFlag::kMC
00997      && header->detector==Detector::kFar)
00998     weight *= 1.+adjustedValues[NCType::kNormalization];
00999 
01000   if(useParameters[NCType::kNCBackground]
01001      && truth->interactionType < 1
01002      && analysis->isCC > 0)
01003     weight *= 1.+adjustedValues[NCType::kNCBackground];
01004 
01005   //CC background is real CC's, not less than 50% complete CC's.
01006   //9/4/07: BJR - >50% complete is still chosen as CC after the data cleaning
01007   if(useParameters[NCType::kCCBackground]
01008      && truth->interactionType > 0
01009      && TMath::Abs(truth->nuFlavor) == 14
01010      && analysis->isNC > 0
01011      //     && truth->eventCompleteness > 0.5
01012      ) {
01013     weight *= 1.+adjustedValues[NCType::kCCBackground];
01014   }
01015   if(useParameters[NCType::kPIDCut]
01016      && analysis->separationParameterPAN < adjustedValues[NCType::kPIDCut])
01017     weight = 0.;
01018 
01019   //new Values for the Low Completeness. It should not be used alone, so it can be dropped in a decond time
01020   if(useParameters[NCType::kLowCompleteness]
01021      && analysis->isNC > 0
01022      && truth->trueVisibleE &&
01023      ((showerEnergyNC/truth->trueVisibleE)<0.3)){
01024     if(showerEnergyNC <= 0.5)
01025       weight *= 1.+0.13*adjustedValues[NCType::kLowCompleteness];
01026     else if (showerEnergyNC > 0.5 && showerEnergyNC <=1.0)
01027       weight *= 1.+0.83*adjustedValues[NCType::kLowCompleteness];
01028     else weight *= 1.+adjustedValues[NCType::kLowCompleteness];
01029   }
01030 
01031   //NCFarCleanNoise +-7.8% if Ereco<0.5 GeV +-1.5% if 0.5<EReco<0.75GeV
01032   if(useParameters[NCType::kNCFarCleanNoise]
01033      && header->detector==Detector::kFar
01034      && analysis->isNC > 0){
01035     if(showerEnergyNC <= 0.5)
01036       weight  *= 1. + 0.078*adjustedValues[NCType::kNCFarCleanNoise];
01037     else if (showerEnergyNC > 0.5 && showerEnergyNC <=0.75)
01038       weight  *= 1. + 0.015*adjustedValues[NCType::kNCFarCleanNoise];
01039     else weight *= 1.;
01040   }
01041 
01042   //NCFarCleanCR +-0.0161*e^(-Ereco/6.96)
01043   if(useParameters[NCType::kNCFarCleanCR]
01044      && header->detector==Detector::kFar
01045      && analysis->isNC > 0){
01046     weight  *= 1. + (0.0161*TMath::Exp(-showerEnergyNC)/6.96)*adjustedValues[NCType::kNCFarCleanCR];
01047   }
01048 
01049   //Systematics for isSimpleCutsClean
01050   //OVERALL cleaning, cuts+Poorly reconstructed events
01051   //+-6%  Ereco< 1GeV
01052   //+-2%  E <1.5 GeV
01053   //+-1%  E>1.5 GeV
01054   if(useParameters[NCType::kNCNearClean] && header->detector==Detector::kNear &&
01055      analysis->isNC > 0){
01056     const double cleaningSigmas=adjustedValues[NCType::kNCNearClean];
01057     if(showerEnergyNC <= 1.){
01058       //cout << "a. energy=" << showerEnergyNC << " weightFactor=" 
01059       //     << 1. + 0.06*cleaningSigmas << endl;
01060       weight *= 1. + 0.06*cleaningSigmas;
01061     }
01062     else if(showerEnergyNC > 1. && showerEnergyNC <=1.5){
01063       //cout << "b. energy=" << showerEnergyNC << " weightFactor=" 
01064       //     << 1. + 0.02*cleaningSigmas << endl;
01065       weight *= 1. + 0.02*cleaningSigmas;
01066     }
01067     else{
01068       //cout << "c. energy=" << showerEnergyNC << " weightFactor=" 
01069       //     << 1. + 0.01*cleaningSigmas << endl;
01070       weight *= 1. + 0.01*cleaningSigmas;
01071     }
01072 
01073   }
01074 
01075   //NCCleanRunDiff survey  +-4% if     Ereco<1 GeV in ND
01076   if(useParameters[NCType::kNCCleanRunDiff]
01077      && header->detector==Detector::kNear
01078      && analysis->isNC > 0){
01079     if(showerEnergyNC <= 1.0)
01080       weight  *= 1. + 0.04*adjustedValues[NCType::kNCCleanRunDiff];
01081     else weight *= 1.;
01082   }
01083 
01084 
01085   //NCRunDiff survey  +-4% if     Ereco<=1 GeV
01086   //                  +-2% if  1 < Ereco < 5 GeV
01087   if(useParameters[NCType::kNCRunDiff]
01088        && analysis->isNC > 0){
01089     if(showerEnergyNC <= 1.0)
01090       weight  *= 1. + 0.04*adjustedValues[NCType::kNCRunDiff];
01091     else if(showerEnergyNC > 1.0 && showerEnergyNC < 5.0)
01092       weight  *= 1. + 0.02*adjustedValues[NCType::kNCRunDiff];
01093     else weight *= 1.;
01094   }
01095 
01096   // Messages are slow
01097   /*
01098   for(int i = NCType::kTrackEnergy; i < NCType::kNCFarCleanCR; ++i){
01099     MAXMSG("NCEventInfo", Msg::kDebug, 1) << adjustedValues[i] << " ";
01100   }
01101   MAXMSG("NCEventInfo", Msg::kDebug, 1) << endl;
01102 
01103   MAXMSG("NCEventInfo", Msg::kDebug, 30)
01104     << trackEnergy << "/" << reco->muEnergy << " "
01105     << showerEnergy << "/" << reco->showerEnergy
01106     << " " << energy << "/" << reco->nuEnergy
01107     << " " << weight << endl;
01108   */
01109 
01110   return weight;
01111 }
01112 
01113 
01114 //---------------------------------------------------------------------
01115 void NCEventInfo::SelectINukeHist(int& offset, int& from, int& to) const
01116 {
01117   assert(truth);
01118 
01119   const double trueY = truth->nuEnergy*truth->hadronicY;
01120 
01121   // pick the histograms to use, based on process but with
01122   // cut on energy. (reason for cut = sparse statistics)
01123   if(truth->resonanceCode == 1001){
01124     if(truth->trueVisibleE < 1.0) offset = kQE;
01125     else if(truth->trueVisibleE < 2.0) offset = kRES;
01126     else offset = kDIS;
01127 
01128     if(trueY < 1.0){
01129       from = kQE;
01130       to = kQE;
01131     }
01132     else if(trueY < 2.0){
01133       from = kRES;
01134       to = kRES;
01135     }
01136     else{
01137       from = kDIS;
01138       to = kDIS;
01139     }
01140   }//end if QE
01141   else if(truth->resonanceCode == 1002
01142           || truth->resonanceCode == 1004){
01143     if(truth->trueVisibleE < 2.0) offset = kRES;
01144     else offset = kDIS;
01145 
01146     if(trueY < 2.0){
01147       from = kRES;
01148       to = kRES;
01149     }
01150     else{
01151       from = kDIS;
01152       to = kDIS;
01153     }
01154   }
01155   else{
01156     from = kDIS;
01157     to = kDIS;
01158     offset = kDIS;
01159   }
01160 }
01161 
01162 
01163 //---------------------------------------------------------------------
01164 double NCEventInfo::SimulateShowerOffset(TH2F* offsetHist, double offset) const
01165 {
01166   // (PAR 2009-11-27) I really don't understand this function, and I
01167   // don't think we use it anyway, so I'm moving the onus for checking
01168   // it to any potential future users
01169   MSG("NCEventInfo", Msg::kFatal) 
01170     << "SimulateShowerOffset is untested."
01171     << "If you really want to use it, read the code"
01172     << "and check it does what you want" << endl;
01173   // Dummy message to make sure it exits
01174   MSG("NCEventInfo", Msg::kFatal) << "Exiting" << endl;
01175 
01176   assert(truth && reco_nom);
01177 
01178   MAXMSG("NCEventInfo", Msg::kDebug, 20)
01179     << "simulate offset "
01180     << offsetHist->GetName()
01181     << " " << offset
01182     << " " << truth->trueVisibleE
01183     << " " << reco_nom->nuEnergy
01184     << " " << reco_nom->muEnergy
01185     << " " << reco_nom->showerEnergy
01186     << endl;
01187 
01188   // don't do anything to IMD
01189   if(truth->resonanceCode==1005) return reco_nom->showerEnergy;
01190   // sufficiently far from zero
01191   if(truth->trueVisibleE > 5.){
01192 
01193     if(reco_nom->showerEnergy+offset < 0.)
01194       return 0.;
01195 
01196     return reco_nom->showerEnergy+offset;
01197   }
01198   // below zero = zero
01199   if(truth->trueVisibleE+offset < 0.) return 0.;
01200 
01201   // find original bin in reco and true visible energy
01202   int iox = offsetHist->GetXaxis()->FindBin(truth->trueVisibleE);
01203   int ioy = offsetHist->GetYaxis()->FindBin(reco_nom->showerEnergy);
01204   double porig = offsetHist->GetBinContent(iox,ioy);
01205 
01206   // find shifted bin
01207   int isx = offsetHist->GetXaxis()->FindBin(truth->trueVisibleE
01208                                             + offset);
01209   int isy = 0;
01210   double pnew = 0;
01211   for(int i = 1; i <= offsetHist->GetNbinsY(); i++){
01212     pnew = offsetHist->GetBinContent(isx,i);
01213     if(pnew >= porig){
01214       isy = i;
01215       break;
01216     }
01217   }
01218 
01219   // if we have moved bins, sample from a uniform distribution
01220   // in the new bins
01221   double eup = offsetHist->GetYaxis()->GetBinUpEdge(isy);
01222   double elow = offsetHist->GetYaxis()->GetBinLowEdge(isy);
01223   double E = gRandom->Rndm()*(eup-elow) + elow;
01224 
01225   // if we haven't moved bins in reco
01226   // do not change the energy
01227   if(isy == ioy) return reco_nom->showerEnergy;
01228 
01229   return E;
01230 }
01231 
01232 
01233 // UNUSED
01234 /*
01235 //---------------------------------------------------------------------
01236 double NCEventInfo::ReweightInuke(TH2F* intranukeFromHist,
01237                                   TH2F* intranukeToHist)
01238 {
01239   double trueShowerE = truth->nuEnergy*truth->hadronicY;
01240 
01241   // don't do anything to IMD
01242   if(truth->resonanceCode==1005) return reco->showerEnergy;
01243   // very high energy showers do not suffer much from intranuke
01244   // also, they are hard to cope with due to poor statistical precision
01245   if(trueShowerE > 15.0) return reco->showerEnergy;
01246 
01247   // find original bin in reco and true visible energy
01248   int iox = intranukeFromHist->GetXaxis()->FindBin(trueShowerE);
01249   int ioy = intranukeFromHist->GetYaxis()->FindBin(reco->showerEnergy);
01250   double porig = intranukeFromHist->GetBinContent(iox, ioy);
01251 
01252   // find new bin in reco energy
01253   int isx = intranukeToHist->GetXaxis()->FindBin(trueShowerE);
01254   int isy = 0;
01255   double pnew = 0;
01256   for(int i = 1; i <= intranukeToHist->GetNbinsY(); i++){
01257     pnew = intranukeToHist->GetBinContent(isx, i);
01258     if(pnew >= porig){
01259       isy = i;
01260       break;
01261     }
01262   }
01263 
01264   // if we have moved bins, sample from a uniform distribution
01265   // in the new bins
01266   double eup = intranukeToHist->GetYaxis()->GetBinUpEdge(isy);
01267   double elow = intranukeToHist->GetYaxis()->GetBinLowEdge(isy);
01268   double E = gRandom->Rndm()*(eup - elow) + elow;
01269 
01270   // if we haven't moved bins in reco
01271   // do not change the energy
01272   if(isy == ioy) return reco->showerEnergy;
01273 
01274   return E;
01275 }
01276 */
01277 
01278 
01279 //----------------------------------------------------------------------
01280 double NCEventInfo::FindTransitionProbability(const NC::OscProb::OscPars* pars,
01281                                               bool useNuE) const
01282 {
01283   assert(header && truth);
01284 
01285   if(header->detector != int(Detector::kFar)) return 1;
01286 
01287   const int from = TMath::Abs(truth->nonOscNuFlavor);
01288   const int to = TMath::Abs(truth->nuFlavor);
01289 
01290   if(from == 14 && to == 12 && !useNuE) return 0;
01291 
01292   return pars->TransitionProbability(from, to,
01293                                      NCType::EEventType(truth->interactionType),
01294                                      NCType::kBaseLineFar,
01295                                      truth->nuEnergy);
01296 }
01297 
01298 
01299 //---------------------------------------------------------------------
01300 void NCEventInfo::SetEventWeight(const bool* useParameters,
01301                                  const vector<double>& adjustedValues,
01302                                  const NC::OscProb::OscPars* pars,
01303                                  SKZPWeightCalculator* skzpcalc,
01304                                  NC::RunUtil::ERunType runType,
01305                                  bool useNue,
01306                                  bool useOscProb)
01307 {
01308   double neugenWeight = 1.;
01309   double skzpWeight=GetSKZPWeight(runType);
01310 
01311   //set the defaults for the systematic parameters from the config
01312   //set the adjustment to be an actual value, the macro should have
01313   //passed in a number of sigma
01314   bool use = false;
01315   for(int i = 0; i < NCType::kNumNeugenParameters; ++i){
01316     if(useParameters[i]){use = true; break;}
01317   }
01318 
01319   if(use){
01320     //Only apply MODBYRS for Carrot or earlier.
01321     /* StringToType is very heavy on the string comparisons...
01322        const char* mcString = (header->softVersion).Data();
01323        ReleaseType::Release_t mcType = ReleaseType::StringToType(mcString);
01324        bool useMOD = ReleaseType::IsCarrot(mcType);
01325     */
01326     const bool useMOD = string(header->softVersion).find("Carrot") != string::npos;
01327     neugenWeight = FindNeugenWeight(useParameters, adjustedValues, useMOD);
01328   }
01329 
01330   // Check all the remaining parameters
01331   for(int i = NCType::kNumNeugenParameters; i < NCType::kNumSystematicParameters; ++i){
01332     if( useParameters[i] ){use = true; break;}
01333   }//end loop over parameters
01334 
01335   double recoWeight = 1;
01336   double crossSectionWeight = 1;
01337   if(use){
01338     crossSectionWeight = FindCrossSectionWeight(useParameters, adjustedValues);
01339     // We need the systematically shifted energies before applying the
01340     // other systematic weights
01341     ShiftEnergies(useParameters, adjustedValues);
01342     recoWeight = FindRecoWeight(useParameters, adjustedValues);
01343   }
01344 
01345   if(useParameters[NCType::kSKZP]){
01346     skzpWeight *=
01347       FindMEGAFitWeightUncertainty(beam->beamType,
01348                                    runType,
01349                                    adjustedValues[NCType::kSKZP],
01350                                    skzpcalc ? skzpcalc : GetSKZPCalc());
01351   }
01352 
01353   const double survivalProb = useOscProb ?
01354     FindTransitionProbability(pars, useNue) : 1;
01355 
01356   reco->weight = neugenWeight*recoWeight*crossSectionWeight*skzpWeight*survivalProb;
01357 }
01358 
01359 //-----------------------------------------------------------------------
01360 double NCEventInfo::GetSKZPWeight(NC::RunUtil::ERunType runType) const
01361 {
01362   switch(runType){
01363   case NC::RunUtil::kRunI:
01364     return reco_nom->weight;
01365   case NC::RunUtil::kRunII:
01366     return reco_nom->weightRunII;
01367   case NC::RunUtil::kRunIII:
01368     return reco_nom->weightRunIII;
01369   default:
01370     assert(0 && "No weight for requested run");
01371   }
01372 }
01373 
01374 //-----------------------------------------------------------------------
01375 bool NCEventInfo::FinalEventCheck(ANtpAnalysisInfo* ana,
01376                                   ANtpRecoInfo* rec) const
01377 {
01378   if(!ana) ana = analysis;
01379   if(!rec) rec = reco_nom;
01380 
01381   assert(ana && header && rec);
01382 
01383   if(ana->isCC > 0 &&
01384      ana->isNC < 1 &&
01385      rec->trackMomentum > 0)
01386     return false;
01387 
01388   if(!header->isGoodData) return false;
01389 
01390   return true;
01391 }
01392 
01393 
01394 //-----------------------------------------------------------------------
01395 void NCEventInfo::SetChainBranches(TChain* ch,
01396                                    TString extractionName,
01397                                    bool setTruthBranch)
01398 {
01399   const TString extractionBranch = "analysis"+extractionName;
01400 
01401   ch->SetBranchStatus("*", 0);
01402   ch->SetBranchStatus("header.*", 1);
01403   ch->SetBranchStatus("beam.*", 1);
01404   ch->SetBranchStatus("reco.*", 1);
01405   ch->SetBranchStatus(extractionBranch+"*", 1);
01406 
01407   ch->SetBranchAddress("header.", &header);
01408   ch->SetBranchAddress("beam.", &beam);
01409   // Would like to set this branch to also fill the "reco" pointer,
01410   // but can't, hence the FillFromChain function
01411   ch->SetBranchAddress("reco.", &reco_nom);
01412   ch->SetBranchAddress(extractionBranch, &analysis);
01413 
01414   if(setTruthBranch){
01415     ch->SetBranchStatus("truth.*", 1);
01416     ch->SetBranchAddress("truth.", &truth);
01417   }
01418 }
01419 
01420 //-----------------------------------------------------------------------
01421 void NCEventInfo::FillFromChain(TChain* ch, int entry)
01422 {
01423   ch->GetEntry(entry);
01424   if(!reco) reco=new ANtpRecoInfo;
01425   *reco=*reco_nom;
01426 }
01427 
01428 
01429 //-----------------------------------------------------------------------
01430 void NCEventInfo::SetInfoObjects(ANtpHeaderInfo*    headerInfo,
01431                                  ANtpBeamInfo*      beamInfo,
01432                                  ANtpEventInfoNC*   eventInfo,
01433                                  ANtpTrackInfoNC*   trackInfo,
01434                                  ANtpShowerInfoNC*  showerInfo,
01435                                  ANtpAnalysisInfo*  analysisInfo,
01436                                  ANtpRecoInfo*      recoInfo,
01437                                  ANtpTruthInfoBeam* truthInfo)
01438 {
01439   header = headerInfo;
01440   beam = beamInfo;
01441   event = eventInfo;
01442   track = trackInfo;
01443   shower = showerInfo;
01444   analysis = analysisInfo;
01445   reco = recoInfo;
01446   truth = truthInfo;
01447 }
01448 
01449 //-----------------------------------------------------------------------
01450 VldTimeStamp NCEventInfo::GetTimestamp() const
01451 {
01452   return VldTimeStamp(header->year, header->month, header->day,
01453                       header->hour, header->minute,
01454                       TMath::FloorNint(header->second));
01455 }

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