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.47 2009/11/17 12:13:06 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 double NCEventInfo::FindRecoWeight(const bool* useParameters,
00891                                    const vector<double>& adjustedValues,
00892                                    double& energy, double& trackEnergy,
00893                                    double& showerEnergy,
00894                                    double  trueShowerEnergy) const
00895 {
00896   assert(analysis);
00897 
00898   //  assert(useParameters.size() == adjustedValues.size());
00899 
00900 
00901   if(TMath::Abs(trackEnergy) > NCType::kMuMassGeV){
00902     double trackMomentum = TMath::Sqrt(SQR(trackEnergy) - SQR(NCType::kMuMassGeV));
00903 
00904     if(useParameters[NCType::kTrackEnergy])
00905       trackMomentum *= 1. + adjustedValues[NCType::kTrackEnergy];
00906 
00907     trackEnergy = TMath::Sqrt(SQR(trackMomentum) + SQR(NCType::kMuMassGeV));
00908   }
00909 
00910   // Only try to shift the shower if there is one
00911   if(!ANtpDefaultValue::IsDefault(showerEnergy)){
00912     //old way of doing it by scaling shower energy
00913     if(useParameters[NCType::kShowerEnergy] &&
00914        !useParameters[NCType::kAbsoluteHadronicCalibration]) {
00915       showerEnergy  *= 1. + adjustedValues[NCType::kShowerEnergy];
00916     }
00917 
00918     if(useParameters[NCType::kAbsoluteHadronicCalibration]){
00919       const double sigma = adjustedValues[NCType::kAbsoluteHadronicCalibration];
00920       const double scale = CalculateAbsoluteHadronicShiftScale(trueShowerEnergy, sigma);
00921       showerEnergy *= scale;
00922     }
00923 
00924     if(useParameters[NCType::kRelativeHadronicCalibration] &&
00925        header->detector == Detector::kFar)
00926       showerEnergy  *= 1. + adjustedValues[NCType::kRelativeHadronicCalibration];
00927 
00928     assert(showerEnergy >= 0);
00929   }
00930 
00931   //new way using mike's histograms
00932 
00933   int offset = kQE;
00934   int from = kQE;
00935   int to = kQE;
00936   SelectINukeHist(offset, from, to);
00937 
00938 //   if(useParameters[1] && adjustedValues[1] < 0.)
00939 //     showerEnergy = ReweightInuke(fINukeFrom[from], fINukeToMinus[to]);
00940 //   else if(useParameters[1] && adjustedValues[1] > 0.)
00941 //     showerEnergy = ReweightInuke(fINukeFrom[from], fINukeToPlus[to]);
00942 
00943   //Shower offset must be greater than 0 to use.
00944   if(useParameters[NCType::kShowerEnergyOffset]
00945      && TMath::Abs(adjustedValues[NCType::kShowerEnergyOffset])>0.0)
00946     showerEnergy  = SimulateShowerOffset(sfINukeHists.offset[offset],
00947                                          adjustedValues[NCType::kShowerEnergyOffset]);
00948 
00949   if(analysis->isNC>0) energy = showerEnergy;
00950   if(analysis->isCC>0) energy = trackEnergy + showerEnergy;
00951 
00952   double weight = 1;
00953 
00954   //adjust the weight for the event based on the parameters to fit
00955   if(useParameters[NCType::kNormalization]
00956      && header->dataType==SimFlag::kMC
00957      && header->detector==Detector::kFar)
00958     weight *= 1.+adjustedValues[NCType::kNormalization];
00959 
00960   if(useParameters[NCType::kNCBackground]
00961      && truth->interactionType < 1
00962      && analysis->isCC > 0)
00963     weight *= 1.+adjustedValues[NCType::kNCBackground];
00964 
00965   //CC background is real CC's, not less than 50% complete CC's.
00966   //9/4/07: BJR - >50% complete is still chosen as CC after the data cleaning
00967   if(useParameters[NCType::kCCBackground]
00968      && truth->interactionType > 0
00969      && TMath::Abs(truth->nuFlavor) == 14
00970      && analysis->isNC > 0
00971      //     && truth->eventCompleteness > 0.5
00972      ) {
00973     weight *= 1.+adjustedValues[NCType::kCCBackground];
00974   }
00975   if(useParameters[NCType::kPIDCut]
00976      && analysis->separationParameterPAN < adjustedValues[NCType::kPIDCut])
00977     weight = 0.;
00978 
00979   //new Values for the Low Completeness. It should not be used alone, so it can be dropped in a decond time
00980   if(useParameters[NCType::kLowCompleteness]
00981      && analysis->isNC > 0
00982      && truth->trueVisibleE &&
00983      ((showerEnergy/truth->trueVisibleE)<0.3)){
00984     if(showerEnergy <= 0.5)
00985       weight *= 1.+0.13*adjustedValues[NCType::kLowCompleteness];
00986     else if (showerEnergy > 0.5 && showerEnergy <=1.0)
00987       weight *= 1.+0.83*adjustedValues[NCType::kLowCompleteness];
00988     else weight *= 1.+adjustedValues[NCType::kLowCompleteness];
00989   }
00990 
00991   //NCFarCleanNoise +-7.8% if Ereco<0.5 GeV +-1.5% if 0.5<EReco<0.75GeV
00992   if(useParameters[NCType::kNCFarCleanNoise]
00993      && header->detector==Detector::kFar
00994      && analysis->isNC > 0){
00995     if(showerEnergy <= 0.5)
00996       weight  *= 1. + 0.078*adjustedValues[NCType::kNCFarCleanNoise];
00997     else if (showerEnergy > 0.5 && showerEnergy <=0.75)
00998       weight  *= 1. + 0.015*adjustedValues[NCType::kNCFarCleanNoise];
00999     else weight *= 1.;
01000   }
01001 
01002   //NCFarCleanCR +-0.0161*e^(-Ereco/6.96)
01003   if(useParameters[NCType::kNCFarCleanCR]
01004      && header->detector==Detector::kFar
01005      && analysis->isNC > 0){
01006     weight  *= 1. + (0.0161*TMath::Exp(-showerEnergy)/6.96)*adjustedValues[NCType::kNCFarCleanCR];
01007   }
01008 
01009   //Systematics for isSimpleCutsClean
01010   //OVERALL cleaning, cuts+Poorly reconstructed events       
01011   //+-6%  Ereco< 1GeV                                                                                                                    
01012   //+-2%  E <1.5 GeV                                                                                                                     
01013   //+-1%  E>1.5 GeV                                                                                                                      
01014   if(useParameters[NCType::kNCNearClean]                                                                                                 
01015      && header->detector==Detector::kNear                                                                                                
01016      && analysis->isNC > 0){                                                                                                             
01017     if(showerEnergy <= 1.)                                                                                                               
01018       weight  *= 1. + 0.06*adjustedValues[NCType::kNCNearClean];                                                                         
01019     else                                                                                                                                 
01020       if (showerEnergy > 1. && showerEnergy <=1.5)                                                                                       
01021         weight  *= 1. + 0.02*adjustedValues[NCType::kNCNearClean];                                                                       
01022       else                                                                                                                               
01023         weight  *= 1. + 0.01*adjustedValues[NCType::kNCNearClean];                                                                       
01024   }                               
01025 
01026   //NCCleanRunDiff survey  +-4% if     Ereco<1 GeV in ND
01027   if(useParameters[NCType::kNCCleanRunDiff]
01028      && header->detector==Detector::kNear
01029      && analysis->isNC > 0){
01030     if(showerEnergy <= 1.0)
01031       weight  *= 1. + 0.04*adjustedValues[NCType::kNCCleanRunDiff];
01032     else weight *= 1.;
01033   }
01034 
01035 
01036   //NCRunDiff survey  +-4% if     Ereco<=1 GeV
01037   //                  +-2% if  1 < Ereco < 5 GeV
01038   if(useParameters[NCType::kNCRunDiff]
01039        && analysis->isNC > 0){
01040     if(showerEnergy <= 1.0)
01041       weight  *= 1. + 0.04*adjustedValues[NCType::kNCRunDiff];
01042     else if(showerEnergy > 1.0 && showerEnergy < 5.0)
01043       weight  *= 1. + 0.02*adjustedValues[NCType::kNCRunDiff];
01044     else weight *= 1.;
01045   }
01046 
01047   // Messages are slow
01048   /*
01049   for(int i = NCType::kTrackEnergy; i < NCType::kNCFarCleanCR; ++i){
01050     MAXMSG("NCEventInfo", Msg::kDebug, 1) << adjustedValues[i] << " ";
01051   }
01052   MAXMSG("NCEventInfo", Msg::kDebug, 1) << endl;
01053 
01054   MAXMSG("NCEventInfo", Msg::kDebug, 30)
01055     << trackEnergy << "/" << reco->muEnergy << " "
01056     << showerEnergy << "/" << reco->showerEnergy
01057     << " " << energy << "/" << reco->nuEnergy
01058     << " " << weight << endl;
01059   */
01060 
01061   return weight;
01062 }
01063 
01064 
01065 //---------------------------------------------------------------------
01066 void NCEventInfo::SelectINukeHist(int& offset, int& from, int& to) const
01067 {
01068   assert(truth);
01069 
01070   const double trueY = truth->nuEnergy*truth->hadronicY;
01071 
01072   // pick the histograms to use, based on process but with
01073   // cut on energy. (reason for cut = sparse statistics)
01074   if(truth->resonanceCode == 1001){
01075     if(truth->trueVisibleE < 1.0) offset = kQE;
01076     else if(truth->trueVisibleE < 2.0) offset = kRES;
01077     else offset = kDIS;
01078 
01079     if(trueY < 1.0){
01080       from = kQE;
01081       to = kQE;
01082     }
01083     else if(trueY < 2.0){
01084       from = kRES;
01085       to = kRES;
01086     }
01087     else{
01088       from = kDIS;
01089       to = kDIS;
01090     }
01091   }//end if QE
01092   else if(truth->resonanceCode == 1002
01093           || truth->resonanceCode == 1004){
01094     if(truth->trueVisibleE < 2.0) offset = kRES;
01095     else offset = kDIS;
01096 
01097     if(trueY < 2.0){
01098       from = kRES;
01099       to = kRES;
01100     }
01101     else{
01102       from = kDIS;
01103       to = kDIS;
01104     }
01105   }
01106   else{
01107     from = kDIS;
01108     to = kDIS;
01109     offset = kDIS;
01110   }
01111 }
01112 
01113 
01114 //---------------------------------------------------------------------
01115 double NCEventInfo::SimulateShowerOffset(TH2F* offsetHist, double offset) const
01116 {
01117   assert(truth && reco_nom);
01118 
01119   MAXMSG("NCEventInfo", Msg::kDebug, 20)
01120     << "simulate offset "
01121     << offsetHist->GetName()
01122     << " " << offset
01123     << " " << truth->trueVisibleE
01124     << " " << reco_nom->nuEnergy
01125     << " " << reco_nom->muEnergy
01126     << " " << reco_nom->showerEnergy
01127     << endl;
01128 
01129   // don't do anything to IMD
01130   if(truth->resonanceCode==1005) return reco_nom->showerEnergy;
01131   // sufficiently far from zero
01132   if(truth->trueVisibleE > 5.){
01133 
01134     if(reco_nom->showerEnergy+offset < 0.)
01135       return 0.;
01136 
01137     return reco_nom->showerEnergy+offset;
01138   }
01139   // below zero = zero
01140   if(truth->trueVisibleE+offset < 0.) return 0.;
01141 
01142   // find original bin in reco and true visible energy
01143   int iox = offsetHist->GetXaxis()->FindBin(truth->trueVisibleE);
01144   int ioy = offsetHist->GetYaxis()->FindBin(reco_nom->showerEnergy);
01145   double porig = offsetHist->GetBinContent(iox,ioy);
01146 
01147   // find shifted bin
01148   int isx = offsetHist->GetXaxis()->FindBin(truth->trueVisibleE
01149                                             + offset);
01150   int isy = 0;
01151   double pnew = 0;
01152   for(int i = 1; i <= offsetHist->GetNbinsY(); i++){
01153     pnew = offsetHist->GetBinContent(isx,i);
01154     if(pnew >= porig){
01155       isy = i;
01156       break;
01157     }
01158   }
01159 
01160   // if we have moved bins, sample from a uniform distribution
01161   // in the new bins
01162   double eup = offsetHist->GetYaxis()->GetBinUpEdge(isy);
01163   double elow = offsetHist->GetYaxis()->GetBinLowEdge(isy);
01164   double E = gRandom->Rndm()*(eup-elow) + elow;
01165 
01166   // if we haven't moved bins in reco
01167   // do not change the energy
01168   if(isy == ioy) return reco_nom->showerEnergy;
01169 
01170   return E;
01171 }
01172 
01173 
01174 // UNUSED
01175 /*
01176 //---------------------------------------------------------------------
01177 double NCEventInfo::ReweightInuke(TH2F* intranukeFromHist,
01178                                   TH2F* intranukeToHist)
01179 {
01180   double trueShowerE = truth->nuEnergy*truth->hadronicY;
01181 
01182   // don't do anything to IMD
01183   if(truth->resonanceCode==1005) return reco->showerEnergy;
01184   // very high energy showers do not suffer much from intranuke
01185   // also, they are hard to cope with due to poor statistical precision
01186   if(trueShowerE > 15.0) return reco->showerEnergy;
01187 
01188   // find original bin in reco and true visible energy
01189   int iox = intranukeFromHist->GetXaxis()->FindBin(trueShowerE);
01190   int ioy = intranukeFromHist->GetYaxis()->FindBin(reco->showerEnergy);
01191   double porig = intranukeFromHist->GetBinContent(iox, ioy);
01192 
01193   // find new bin in reco energy
01194   int isx = intranukeToHist->GetXaxis()->FindBin(trueShowerE);
01195   int isy = 0;
01196   double pnew = 0;
01197   for(int i = 1; i <= intranukeToHist->GetNbinsY(); i++){
01198     pnew = intranukeToHist->GetBinContent(isx, i);
01199     if(pnew >= porig){
01200       isy = i;
01201       break;
01202     }
01203   }
01204 
01205   // if we have moved bins, sample from a uniform distribution
01206   // in the new bins
01207   double eup = intranukeToHist->GetYaxis()->GetBinUpEdge(isy);
01208   double elow = intranukeToHist->GetYaxis()->GetBinLowEdge(isy);
01209   double E = gRandom->Rndm()*(eup - elow) + elow;
01210 
01211   // if we haven't moved bins in reco
01212   // do not change the energy
01213   if(isy == ioy) return reco->showerEnergy;
01214 
01215   return E;
01216 }
01217 */
01218 
01219 
01220 //----------------------------------------------------------------------
01221 double NCEventInfo::FindTransitionProbability(const NC::OscProb::OscPars* pars,
01222                                               bool useNuE) const
01223 {
01224   assert(header && truth);
01225 
01226   if(header->detector != int(Detector::kFar)) return 1;
01227 
01228   const int from = TMath::Abs(truth->nonOscNuFlavor);
01229   const int to = TMath::Abs(truth->nuFlavor);
01230 
01231   if(from == 14 && to == 12 && !useNuE) return 0;
01232 
01233   return pars->TransitionProbability(from, to,
01234                                      NCType::EEventType(truth->interactionType),
01235                                      NCType::kBaseLineFar,
01236                                      truth->nuEnergy);
01237 }
01238 
01239 
01240 //---------------------------------------------------------------------
01241 void NCEventInfo::SetEventWeight(const bool* useParameters,
01242                                  const vector<double>& adjustedValues,
01243                                  const NC::OscProb::OscPars* pars,
01244                                  SKZPWeightCalculator* skzpcalc,
01245                                  NC::RunUtil::ERunType runType,
01246                                  bool useNue,
01247                                  bool useOscProb)
01248 {
01249   double neugenWeight = 1.;
01250   double skzpWeight=GetSKZPWeight(runType);
01251 
01252   //set the defaults for the systematic parameters from the config
01253   //set the adjustment to be an actual value, the macro should have
01254   //passed in a number of sigma
01255   bool use = false;
01256   for(int i = 0; i < NCType::kNumNeugenParameters; ++i){
01257     if(useParameters[i]){use = true; break;}
01258   }
01259 
01260   if(use){
01261     //Only apply MODBYRS for Carrot or earlier.
01262     /* StringToType is very heavy on the string comparisons...
01263        const char* mcString = (header->softVersion).Data();
01264        ReleaseType::Release_t mcType = ReleaseType::StringToType(mcString);
01265        bool useMOD = ReleaseType::IsCarrot(mcType);
01266     */
01267     const bool useMOD = string(header->softVersion).find("Carrot") != string::npos;
01268     neugenWeight = FindNeugenWeight(useParameters, adjustedValues, useMOD);
01269   }
01270 
01271   // Check all the remaining parameters
01272   for(int i = NCType::kNumNeugenParameters; i < NCType::kNumSystematicParameters; ++i){
01273     if( useParameters[i] ){use = true; break;}
01274   }//end loop over parameters
01275 
01276   double energy = reco_nom->nuEnergy;
01277   double trackEnergy = reco_nom->muEnergy;
01278   double showerEnergy = reco_nom->showerEnergy;
01279   double showerEnergyNC = reco_nom->showerEnergyNC;
01280   double showerEnergyCC = reco_nom->showerEnergyCC;
01281 
01282   double recoWeight = 1;
01283   double crossSectionWeight = 1;
01284   if(use){
01285     crossSectionWeight = FindCrossSectionWeight(useParameters, adjustedValues);
01286 
01287     // Only need to shift track energy and total energy once. Other times
01288     // throw the result away in this variable.
01289     double junk = 0;
01290 
01291     const double trueShowerEnergy = truth->showerEnergy;
01292 
01293     recoWeight = FindRecoWeight(useParameters, adjustedValues, energy,
01294                                 trackEnergy, showerEnergy, trueShowerEnergy);
01295     // Do this again to adjust the NC shower energy too
01296     FindRecoWeight(useParameters, adjustedValues, junk,
01297                    junk, showerEnergyNC, trueShowerEnergy);
01298     // ...and the CC shower energy
01299     FindRecoWeight(useParameters, adjustedValues, junk,
01300                    junk, showerEnergyCC, trueShowerEnergy);
01301   }
01302 
01303   reco->nuEnergy = energy;
01304   reco->muEnergy = trackEnergy;
01305   reco->showerEnergy = showerEnergy;
01306   reco->showerEnergyNC = showerEnergyNC;
01307   reco->showerEnergyCC = showerEnergyCC;
01308   reco->nuEnergyCC = trackEnergy + showerEnergyCC;
01309   reco->nuEnergyNC = showerEnergyNC ? showerEnergyNC : ANtpDefaultValue::kDouble;
01310 
01311 
01312   if(useParameters[NCType::kSKZP]){
01313     skzpWeight *=
01314       FindMEGAFitWeightUncertainty(beam->beamType,
01315                                    runType,
01316                                    adjustedValues[NCType::kSKZP],
01317                                    skzpcalc ? skzpcalc : GetSKZPCalc());
01318   }
01319 
01320   const double survivalProb = useOscProb ?
01321     FindTransitionProbability(pars, useNue) : 1;
01322 
01323   reco->weight = neugenWeight*recoWeight*crossSectionWeight*skzpWeight*survivalProb;
01324 }
01325 
01326 //-----------------------------------------------------------------------
01327 double NCEventInfo::GetSKZPWeight(NC::RunUtil::ERunType runType) const
01328 {
01329   switch(runType){
01330   case NC::RunUtil::kRunI:
01331     return reco_nom->weight;
01332   case NC::RunUtil::kRunII:
01333     return reco_nom->weightRunII;
01334   case NC::RunUtil::kRunIII:
01335     return reco_nom->weightRunIII;
01336   default:
01337     assert(0 && "No weight for requested run");
01338   }
01339 }
01340 
01341 //-----------------------------------------------------------------------
01342 bool NCEventInfo::FinalEventCheck(ANtpAnalysisInfo* ana,
01343                                   ANtpRecoInfo* rec) const
01344 {
01345   if(!ana) ana = analysis;
01346   if(!rec) rec = reco_nom;
01347 
01348   assert(ana && header && rec);
01349 
01350   if(ana->isCC > 0 &&
01351      ana->isNC < 1 &&
01352      rec->trackMomentum > 0)
01353     return false;
01354 
01355   if(header->detector == Detector::kNear &&
01356      !NC::RunUtil::IsNDRunGood(header->run, header->subRun))
01357     return false;
01358 
01359   return true;
01360 }
01361 
01362 
01363 //-----------------------------------------------------------------------
01364 void NCEventInfo::SetChainBranches(TChain* ch,
01365                                    TString extractionName,
01366                                    bool setTruthBranch)
01367 {
01368   const TString extractionBranch = "analysis"+extractionName;
01369 
01370   ch->SetBranchStatus("*", 0);
01371   ch->SetBranchStatus("header.*", 1);
01372   ch->SetBranchStatus("beam.*", 1);
01373   ch->SetBranchStatus("reco.*", 1);
01374   ch->SetBranchStatus(extractionBranch+"*", 1);
01375 
01376   ch->SetBranchAddress("header.", &header);
01377   ch->SetBranchAddress("beam.", &beam);
01378   // Would like to set this branch to also fill the "reco" pointer,
01379   // but can't, hence the FillFromChain function
01380   ch->SetBranchAddress("reco.", &reco_nom);
01381   ch->SetBranchAddress(extractionBranch, &analysis);
01382 
01383   if(setTruthBranch){
01384     ch->SetBranchStatus("truth.*", 1);
01385     ch->SetBranchAddress("truth.", &truth);
01386   }
01387 }
01388 
01389 //-----------------------------------------------------------------------
01390 void NCEventInfo::FillFromChain(TChain* ch, int entry)
01391 {
01392   ch->GetEntry(entry);
01393   if(!reco) reco=new ANtpRecoInfo;
01394   *reco=*reco_nom;
01395 }
01396 
01397 
01398 //-----------------------------------------------------------------------
01399 void NCEventInfo::SetInfoObjects(ANtpHeaderInfo*    headerInfo,
01400                                  ANtpBeamInfo*      beamInfo,
01401                                  ANtpEventInfoNC*   eventInfo,
01402                                  ANtpTrackInfoNC*   trackInfo,
01403                                  ANtpShowerInfoNC*  showerInfo,
01404                                  ANtpAnalysisInfo*  analysisInfo,
01405                                  ANtpRecoInfo*      recoInfo,
01406                                  ANtpTruthInfoBeam* truthInfo)
01407 {
01408   header = headerInfo;
01409   beam = beamInfo;
01410   event = eventInfo;
01411   track = trackInfo;
01412   shower = showerInfo;
01413   analysis = analysisInfo;
01414   reco = recoInfo;
01415   truth = truthInfo;
01416 }
01417 
01418 //-----------------------------------------------------------------------
01419 VldTimeStamp NCEventInfo::GetTimestamp() const
01420 {
01421   return VldTimeStamp(header->year, header->month, header->day,
01422                       header->hour, header->minute,
01423                       TMath::FloorNint(header->second));
01424 }

Generated on Mon Nov 23 05:27:29 2009 for loon by  doxygen 1.3.9.1