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

NCExtrapolationModule.cxx

Go to the documentation of this file.
00001 
00002 //$Id: NCExtrapolationModule.cxx,v 1.234 2010/01/19 17:02:22 rodriges Exp $
00003 //
00004 //NCExtrapolationModule.cxx
00005 //
00006 //Module for analyzing beam data for nc analysis
00007 //
00008 //B. Rebel 10/2004
00010 
00011 #include "NCUtils/Extrapolation/NCExtrapolationModule.h"
00012 
00013 #include "NCUtils/Extrapolation/NCCoordinateConverter.h"
00014 #include "NCUtils/Extrapolation/NCEventAdder.h"
00015 #include "NCUtils/Extrapolation/NCExtrapolation.h"
00016 #include "NCUtils/Extrapolation/NCFitMaster.h"
00017 #include "NCUtils/Extrapolation/NCPOTCounter.h"
00018 #include "NCUtils/NCOscProb.h"
00019 #include "NCUtils/NCRunUtil.h"
00020 
00021 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00022 #include "AnalysisNtuples/ANtpBeamInfo.h"
00023 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00024 #include "AnalysisNtuples/ANtpRecoInfo.h"
00025 #include "AnalysisNtuples/ANtpTruthInfoBeam.h"
00026 
00027 #include "MessageService/MsgService.h"
00028 
00029 #include "TCanvas.h"
00030 #include "TDirectory.h"
00031 #include "TFile.h"
00032 #include "TLegend.h"
00033 #include "TRandom3.h"
00034 #include "TSystem.h"
00035 #include "TStopwatch.h"
00036 
00037 #include <cassert>
00038 #include <algorithm>
00039 
00040 using namespace BeamType;
00041 using namespace NCType;
00042 
00043 CVSID("$Id: NCExtrapolationModule.cxx,v 1.234 2010/01/19 17:02:22 rodriges Exp $");
00044 
00045 //......................................................................
00046 NCExtrapolationModule::NCExtrapolationModule() :
00047   fTrueOscPars(0),
00048   fNumMockExperiments(0),
00049   fPOTCount(0)
00050 {
00051   MSG("JobC", Msg::kDebug) << "NCExtrapolationModule::Constructor" << endl;
00052 
00053   // "Special" means studying systematic shifts.
00054   // These are the TOm selection variables.
00055   for(int k = 3; k < 6; ++k){
00056     fDQNearMCTotalSpecial.push_back(CreateSpecialPlot(k, "NearMCTotalSpecial"));
00057   }
00058 
00059   fEventInfo.header = new ANtpHeaderInfo;
00060   fEventInfo.beam = new ANtpBeamInfo;
00061   fEventInfo.reco = new ANtpRecoInfo;
00062   fEventInfo.analysis = new ANtpAnalysisInfo;
00063   fEventInfo.truth = new ANtpTruthInfoBeam;
00064 
00065   fPOTCount = new NCPOTCounter;
00066 }
00067 
00068 enum{
00069   kDQEventLength      = 3,
00070   kDQNumTracks        = 4,
00071   kDQTrackExtension   = 5
00072 };
00073 
00074 //----------------------------------------------------------------------
00075 TH1* NCExtrapolationModule::CreateSpecialPlot(int k, TString type) const
00076 {
00077   assert(k >= 3 && k < 6);
00078 
00079   // Definition of a data quality plot: name, title, binning
00080   struct DQDef
00081   {
00082     // Order of elements is important, this is how we are initialised
00083     TString name;
00084     TString title;
00085     int bins;
00086     double start;
00087     double end;
00088   };
00089 
00090   const DQDef kDQVars[6] = {
00091     {"?", "?", -1, -1, -1},
00092     {"?", "?", -1, -1, -1},
00093     {"?", "?", -1, -1, -1},
00094     {"eventLength",    "Event Length (planes)",    50,   0,  500},
00095     {"numTracks",      "Number of Tracks",         10,   0,   10},
00096     {"trackExtension", "Track Extension (planes)", 50, -30,   20}
00097   };
00098 
00099   TH1* ret = new TH1D(kDQVars[k].name+type, "", kDQVars[k].bins, kDQVars[k].start, kDQVars[k].end);
00100 
00101   ret->GetXaxis()->SetTitle(kDQVars[k].title);
00102   ret->GetYaxis()->SetTitle("Events");
00103 
00104   ret->GetXaxis()->CenterTitle();
00105   ret->GetYaxis()->CenterTitle();
00106 
00107   return ret;
00108 }
00109 
00110 //----------------------------------------------------------------------
00111 NCExtrapolationModule::~NCExtrapolationModule()
00112 {
00113   MSG("JobC", Msg::kDebug) << "NCExtrapolationModule::Destructor" << endl;
00114 
00115   for(unsigned int n = 0; n < fExtrapolations.size(); ++n) delete fExtrapolations[n];
00116   for(unsigned int n = 0; n < fFitMasters.size(); ++n) delete fFitMasters[n];
00117 
00118   if(fEventInfo.header) delete fEventInfo.header;
00119   if(fEventInfo.beam) delete fEventInfo.beam;
00120   if(fEventInfo.reco) delete fEventInfo.reco;
00121   if(fEventInfo.reco_nom) delete fEventInfo.reco_nom;
00122   if(fEventInfo.truth) delete fEventInfo.truth;
00123   if(fEventInfo.analysis) delete fEventInfo.analysis;
00124 
00125   if(fTrueOscPars) delete fTrueOscPars;
00126 
00127   if(fPOTCount) delete fPOTCount;
00128 
00129   for(unsigned int n = 0; n < fFDMCSample.size(); ++n){
00130     delete fFDMCSample[n]->header;
00131     delete fFDMCSample[n]->beam;
00132     delete fFDMCSample[n]->reco;
00133     delete fFDMCSample[n]->reco_nom;
00134     delete fFDMCSample[n]->truth;
00135     delete fFDMCSample[n]->analysis;
00136     delete fFDMCSample[n];
00137   }
00138 
00139   for(unsigned int n = 0; n < fMockFits.size(); ++n) delete fMockFits[n];
00140 }
00141 
00142 //----------------------------------------------------------------------
00143 void NCExtrapolationModule::DrawDataQualityPlots()
00144 {
00145   // get a pointer to the current directory
00146   // this is one of the output files
00147   TDirectory* saveDir = gDirectory;
00148 
00149   //loop over the data quality histograms
00150   //make folders for data/mc and subfolders for near/far
00151   TDirectory* dir = saveDir->mkdir("DataQuality", "DataQuality");
00152   dir->cd();
00153 
00154   TDirectory* near = dir->mkdir("NearDetector", "NearDetector");
00155 
00156   near->cd();
00157 
00158   if(fMakeDQPlotsSpecial) DrawDataQualityPlotsSpecial();
00159 
00160   saveDir->cd();
00161 }
00162 
00163 //----------------------------------------------------------------------
00164 void NCExtrapolationModule::DrawDataQualityPlotsSpecial()
00165 {
00166   for(int dist = 0; dist < 3; ++dist){
00167 
00168     fDQNearMCTotalSpecial[dist]->Write();
00169 
00170 
00171     TString canvName = fDQNearMCTotalSpecial[dist]->GetName();
00172     //    int index = canvName.Index("MC");
00173     canvName += "Canv";
00174     TCanvas *canv = new TCanvas(canvName, canvName, 150, 10, 900, 600);
00175     TLegend *leg = new TLegend(0.75, 0.75, 0.95, 0.95);
00176     leg->SetBorderSize(0);
00177 
00178     fDQNearMCTotalSpecial[dist]->Draw("");
00179     leg->AddEntry(fDQNearMCTotalSpecial[dist], "MC Total", "l");
00180     leg->Draw();
00181 
00182     gDirectory->Append(canv);
00183 
00184   }//end loop over dists
00185 }
00186 
00187 //----------------------------------------------------------------------
00188 void NCExtrapolationModule::Run()
00189 {
00190   fConfig.Print(); // Print out the configuration in use.
00191 
00192   assert(fTrueOscPars);
00193 
00194   //get the pot for the different beams
00195   const NCType::EFileType fileType = fUseMockData ? NCType::kMockFile : NCType::kBeamFile;
00196 
00197   //use following map for FD MC
00198   fPOTCount->SetPOTValues(fDataPOTNear,          Detector::kNear,
00199                           NCType::kBeamFile,     NCType::kData);
00200 
00201   fPOTCount->SetPOTValues(fMCPOTNear,            Detector::kNear,
00202                           NCType::kBeamFile,     NCType::kMC);
00203 
00204   fPOTCount->SetPOTValues(fDataPOTFar,           Detector::kFar,
00205                           fileType,              NCType::kData);
00206 
00207   fPOTCount->SetPOTValues(fMCPOTFar,             Detector::kFar,
00208                           NCType::kBeamFile,     NCType::kMC);
00209 
00210   fPOTCount->SetPOTValues(fMCPOTFarTau,          Detector::kFar,
00211                           NCType::kTauFile,      NCType::kMC);
00212 
00213   fPOTCount->SetPOTValues(fMCPOTFarElectron,     Detector::kFar,
00214                           NCType::kElectronFile, NCType::kMC);
00215 
00216   MSG("NCExtrapolationModule", Msg::kInfo) << "Done setting POT values" << endl;
00217 
00218 
00219   ChainMap dataND;
00220   ChainMap mcND;
00221   ChainMap dataFD;
00222   ChainMap mcFD;
00223   ChainMap mcTauFD;
00224   ChainMap mcElectronFD;
00225 
00226   // The beamtype/runperiod pairs we're using
00227   vector<NCBeam::Info> infos;
00228 
00229   for(unsigned int bidx = 0; bidx < fBeamIndex.size(); ++bidx){
00230     const BeamType::BeamType_t bt = fBeamIndex[bidx];
00231     for(unsigned int runPidx=0; runPidx < fRunsToUse.size(); ++runPidx){
00232       const NC::RunUtil::ERunType runPeriod = fRunsToUse[runPidx];
00233       const NCBeam::Info info(bt, runPeriod);
00234 
00235       infos.push_back(info);
00236     }
00237   }
00238 
00239   for(unsigned int i=0; i<infos.size(); ++i){
00240     NCBeam::Info info=infos[i];
00241     dataND[info] = new TChain("uDST");
00242     mcND[info] = new TChain("uDST");
00243     dataFD[info] = new TChain("uDST");
00244     mcFD[info] = new TChain("uDST");
00245     mcTauFD[info] = new TChain("uDST");
00246     mcElectronFD[info] = new TChain("uDST");
00247   }
00248 
00249   AddFilesToChain(dataND,  Detector::kNear, NCType::kBeamFile, NCType::kData);
00250   AddFilesToChain(mcND,    Detector::kNear, NCType::kBeamFile, NCType::kMC);
00251   AddFilesToChain(dataFD,  Detector::kFar,  fileType,          NCType::kData);
00252   AddFilesToChain(mcFD,    Detector::kFar,  NCType::kBeamFile, NCType::kMC);
00253   AddFilesToChain(mcTauFD, Detector::kFar,  NCType::kTauFile,  NCType::kMC);
00254   AddFilesToChain(mcElectronFD, Detector::kFar, NCType::kElectronFile, NCType::kMC);
00255 
00256   const TString ext = NCType::kExtractionNames[fExtractionType];
00257 
00258   for(unsigned int i=0; i<infos.size(); ++i){
00259     NCBeam::Info info=infos[i];
00260     fEventInfo.SetChainBranches(dataND[info],       ext, fUseMCAsData);
00261     fEventInfo.SetChainBranches(dataFD[info],       ext, fUseMCAsData);
00262     fEventInfo.SetChainBranches(mcND[info],         ext, true);
00263     fEventInfo.SetChainBranches(mcFD[info],         ext, true);
00264     fEventInfo.SetChainBranches(mcTauFD[info],      ext, true);
00265     fEventInfo.SetChainBranches(mcElectronFD[info], ext, true);
00266   } 
00267 
00268 
00269   CreateExtrapolations(fExtrapolationsList);
00270 
00271   PrepareForExtrapolation();
00272 
00273   NC::IEventAdder* eventAdder = NC::EventAdderBuilder(fConfig);
00274 
00275   for(unsigned int i=0; i<infos.size(); ++i){
00276     NCBeam::Info info=infos[i];
00277     eventAdder->AddEvents(this, &fEventInfo,
00278                           dataND[info], mcND[info],
00279                           dataFD[info], mcFD[info], mcTauFD[info], mcElectronFD[info]);
00280   }
00281   delete eventAdder;
00282 
00283   ExtrapolateNearToFar();
00284 
00285   if(fNumMockExperiments > 0) DoMockExperiments();
00286 
00287   //make a file and the trees to go into the file
00288 
00289   MSG("NCExtrapolationModule", Msg::kInfo) << "fFileName = " << fFileName << endl;
00290 
00291   TFile ntpFile(fFileName, "RECREATE");
00292   ntpFile.cd();
00293 
00294   for(unsigned int k = 0; k < fExtrapolations.size(); ++k){
00295     TDirectory* saveDir = gDirectory;
00296     TString plotName = "plots"+fExtrapolations[k]->GetShortName();
00297     TDirectory* newDir = gDirectory->mkdir(plotName, plotName);
00298 
00299     // In case we failed to make the new directory then this way
00300     // probably gives us the best chance of rescuing the plots
00301     if(newDir) newDir->cd();
00302     fFitMasters[k]->WriteResources();
00303     if(newDir) newDir->cd();
00304     fExtrapolations[k]->WriteResources(fTrueOscPars);
00305 
00306     saveDir->cd();
00307   }
00308 
00309   if(!fUseMCAsData && !fUseMockData) DrawDataQualityPlots();
00310 
00311   ntpFile.cd();
00312   fConfig.SetName("config_registry");
00313   fConfig.Write();
00314 
00315   if(!fMockFits.empty()){
00316     ntpFile.cd();
00317     gDirectory->mkdir("mock_expts")->cd();
00318     for(unsigned int n = 0; n < fMockFits.size(); ++n){
00319       Registry* r = fMockFits[n];
00320       r->SetName(TString::Format("expt_%d", n));
00321       r->Write();
00322     }
00323     ntpFile.cd();
00324   }
00325 
00326   MSG("NCExtrapolationModule", Msg::kInfo) << "Writing Final File!" << endl;
00327 
00328   ntpFile.Write();
00329   ntpFile.Close();
00330 
00331   if(fSaveExtrapolationsFile != ""){
00332     TFile saveFile(fSaveExtrapolationsFile, "RECREATE");
00333     for(unsigned int k = 0; k < fExtrapolations.size(); ++k)
00334       fExtrapolations[k]->Write();
00335     saveFile.Close();
00336   }
00337 }
00338 
00339 //......................................................................
00340 void NCExtrapolationModule::AddExtrapolation(NCExtrapolationFactory* e)
00341 {
00342   std::vector<NCExtrapolationFactory*>& facts = GetExtrapolationFactories();
00343   for(unsigned int n = 0; n < facts.size(); ++n){
00344     // If this happens it means that extrapolations have got registered
00345     // twice somehow. Check your environment, and rebuild stuff, including
00346     // the macro.
00347     assert(e->GetCodeName() != facts[n]->GetCodeName());
00348   }
00349   facts.push_back(e);
00350 }
00351 
00352 //......................................................................
00353 void NCExtrapolationModule::SetMCExposureForBeam(NCBeam::Info beam, double pot)
00354 {
00355   fPOTCount->SetMCExposureForBeam(beam, pot);
00356 }
00357 
00358 //......................................................................
00359 const Registry& NCExtrapolationModule::DefaultConfig() const
00360 {
00361   static Registry r;
00362 
00363   r.UnLockValues();
00364 
00365   r.Set("DataMCPath",             "dataFiles/*.root");
00366   r.Set("FarDataPath",            "dataFiles/*.root");
00367   r.Set("FileName",               "extrapolationFile.root");
00368 
00369   r.Set("OscillationModel",       NCType::kSterileFraction);
00370   r.Set("UseMCAsData",            false);
00371   r.Set("SplitMC",                false);
00372   r.Set("SplitMCSeed",            -1);
00373   r.Set("ExtractionType",         NCType::kNCCCExtractionCuts);
00374   r.Set("SingleSpectrum",         false);
00375   r.Set("ExtrapolationsList",     "");
00376   r.Set("BeamType",               "L010z185i");
00377   r.Set("UseMockData",            false);
00378   r.Set("MockDataSet",            "F21910001");
00379 
00380   TString runsToUse;
00381   for(int n = 0; n <= NC::RunUtil::kMaxRun; ++n)
00382     runsToUse += TString::Format("%d ", n);
00383   r.Set("RunsToUse",              runsToUse);
00384 
00385   r.Set("OscPars",                0);
00386   r.Set("NumMockExperiments",     0);
00387   r.Set("MockExperimentsSeed",    0);
00388   r.Set("LoadExtrapolationsFile", "");
00389   r.Set("IncludeDataFromLoadedExtrapolations", false);
00390   r.Set("SaveExtrapolationsFile", "");
00391 
00392   r.Set("MakeDQPlotsSpecial",     false);
00393 
00394   // Get the default configurations for all the registered extrapolations
00395   vector<NCExtrapolationFactory*> facts =  GetExtrapolationFactories();
00396   for(unsigned int n = 0; n < facts.size(); ++n)
00397     r.Merge(facts[n]->DefaultConfig());
00398 
00399   //PID sensitivity study
00400   r.Set("UsePIDCustomCut",        false);
00401   r.Set("PIDCustomCut",           0.0);
00402 
00403   r.Set("MakeShiftedBeams",       false);
00404   r.Set("ShiftedBeamsSimpleOnly", false);
00405   r.Set("SingleShiftedBeam",      -1);
00406 
00407   //set the defaults for the systematic parameters
00408   //set them all off for fitting and changing mc by default
00409   TString adjust   = "Adjust";
00410   TString mcAsData = "ChangeMCAsData";
00411   TString fit      = "Fit";
00412   for(int i = 0; i < NCType::kNumSystematicParameters; ++i){
00413     r.Set(NCType::kParams[i].name,            false);
00414     r.Set(mcAsData + NCType::kParams[i].name, false);
00415     r.Set(adjust + NCType::kParams[i].name,   0); // measured in sigma
00416     r.Set(fit + NCType::kParams[i].name,      false);
00417   }
00418 
00419   // Add all the configuration that NCExtrapolation knows how to read
00420   r.Merge(NCExtrapolation::DefaultConfig());
00421 
00422   r.Merge(NC::FitMaster::DefaultConfig());
00423 
00424   r.Merge(NC::EventAdderDefaultConfig());
00425 
00426   r.LockValues();
00427   return r;
00428 }
00429 
00430 //......................................................................
00431 void NCExtrapolationModule::Config(const Registry& r)
00432 {
00433   fConfig = r;
00434 
00435   int         tmpb;  // a temp bool.
00436   int         tmpi;  // a temp int.
00437   double      tmpd;  // a temp double.
00438   const char* tmps;  // a temp string
00439 
00440   if (r.Get("DataMCPath",            tmps)){
00441     //for some reason the TSystemDirectory constructor can't resolve
00442     //environmental variables, so just take care of it here
00443     TString temp = tmps;
00444     // Assume the form $ENVVAR/path
00445     if(temp.Contains("$")){
00446       int pos = temp.Index("/"); // find the first /
00447       temp.Resize(pos); // and truncate at it
00448       temp.Remove(TString::kLeading, '$'); // drop the $ off the front
00449       fDataMCPath = tmps; // Copy the original string
00450       // and then replace the part that we think is the environment variable
00451       fDataMCPath.Replace(0, pos, gSystem->Getenv(temp));
00452     }
00453     else fDataMCPath = temp;
00454     // Add a trailing slash so that concatenating the path later will work
00455     if(!fDataMCPath.EndsWith("/")) fDataMCPath += "/";
00456   }
00457   if(r.Get("FileName",               tmps)) fFileName           = tmps;
00458 
00459   if(r.Get("OscillationModel",       tmpi)) fOscillationModel   = NCType::EOscModel(tmpi);
00460   if(r.Get("UseMCAsData",            tmpb)) fUseMCAsData        = tmpb;
00461   if(r.Get("ExtractionType",         tmpi)) fExtractionType     = NCType::EExtraction(tmpi);
00462   if(r.Get("SingleSpectrum",         tmpb)) fSingleSpectrum     = tmpb;
00463   if(r.Get("ExtrapolationsList",     tmps)) fExtrapolationsList = tmps;
00464   if(r.Get("UseMockData",            tmpb)) fUseMockData        = tmpb;
00465   if(r.Get("UsePIDCustomCut",        tmpb)) fUsePIDCustomCut    = tmpb;
00466   if(r.Get("PIDCustomCut",           tmpd)) fPIDCustomCut       = tmpd;
00467 
00468   if(r.Get("MakeShiftedBeams",       tmpb)) fShiftedBeams       = tmpb;
00469   if(r.Get("ShiftedBeamsSimpleOnly", tmpb)) fSimpleShiftedBeams = tmpb;
00470   if(r.Get("SingleShiftedBeam",      tmpi)) fSingleShiftedBeam  = tmpi;
00471 
00472   if(r.Get("RunsToUse",              tmps)){
00473     fRunsToUse.clear();
00474     vector<int> runs = NC::Utility::ParseNumberList(tmps);
00475     for(unsigned int n = 0; n < runs.size(); ++n)
00476       fRunsToUse.push_back(NC::RunUtil::ERunType(runs[n]));
00477   }
00478 
00479   if(r.Get("NumMockExperiments",     tmpi)) fNumMockExperiments  = tmpi;
00480   if(r.Get("MockExperimentsSeed",    tmpi)) fMockExperimentsSeed = tmpi;
00481   if(r.Get("LoadExtrapolationsFile", tmps)) fLoadExtrapolationsFile = tmps;
00482   if(r.Get("IncludeDataFromLoadedExtrapolations", tmpb))
00483      fIncludeDataFromLoadedExtrapolations = tmpb;
00484   if(r.Get("SaveExtrapolationsFile", tmps)) fSaveExtrapolationsFile = tmps;
00485 
00486   if(r.Get("MakeDQPlotsSpecial",     tmpb)) fMakeDQPlotsSpecial  = tmpb;
00487 
00488   assert(sizeof(NC::OscProb::OscPars*) == sizeof(int));
00489   if(r.Get("OscPars", tmpi)) fTrueOscPars = (NC::OscProb::OscPars*)(tmpi);
00490 
00491   if (r.Get("BeamType",              tmps))
00492     fBeamIndex = NCType::BeamListFromString(tmps);
00493 
00494   fPOTCount->Config(r, fBeamIndex, fRunsToUse);
00495 }
00496 
00497 
00498 //-----------------------------------------------------------------------
00499 void NCExtrapolationModule::AddFilesToChain(ChainMap& chainMap,
00500                                             Detector::Detector_t det,
00501                                             NCType::EFileType fileType,
00502                                             NCType::EDataMC dataMC)
00503 {
00504   MSG("NCExtrapolationModule", Msg::kInfo) << "fDataMCPath = "
00505                                            << fDataMCPath << endl;
00506 
00507   for(ChainMap::iterator it=chainMap.begin();
00508       it != chainMap.end();
00509       ++it){
00510 
00511     const NCBeam::Info info=it->first;
00512     const TString beamType=BeamType::AsString(info.GetBeamType());
00513 
00514     vector<TString> files = fPOTCount->GetListOfFiles(info, fileType,
00515                                                       det, dataMC);
00516     
00517     for(unsigned int de = 0; de < files.size(); ++de) {
00518       it->second->Add(fDataMCPath+beamType+"/"+files[de]);
00519       MSG("NCExtrapolationModule", Msg::kInfo) 
00520         << "Adding "
00521         << fDataMCPath+beamType
00522         << "/"+files[de] << " to "
00523         << NCType::FileTypeAsString(fileType) << " chain" << endl;
00524 
00525     }//end loop over files in directory
00526   }//end loop over map
00527 }
00528 
00529 
00530 //-----------------------------------------------------------------------
00531 void NCExtrapolationModule::FillDataQualityPlotsSpecial(std::vector<TH1*>& dq, bool osc)
00532 {
00533 
00534   osc=false;
00535 
00536   //dont bother with events outside the fiducial volume
00537   if(fEventInfo.reco->inFiducialVolume < 1) return;
00538 
00539   double weight;
00540   switch(NC::RunUtil::FindRunType(fEventInfo.header)){
00541   case NC::RunUtil::kRunI: 
00542     weight=fEventInfo.reco->weight;
00543     break;
00544   case NC::RunUtil::kRunII: 
00545     weight=fEventInfo.reco->weightRunII;
00546     break;
00547   case NC::RunUtil::kRunIII: 
00548     weight=fEventInfo.reco->weightRunIII;
00549     break;
00550   default:
00551     assert(0 && "Unknown runtype");
00552   }
00553 
00554   double trackExtension = -1.*fEventInfo.reco->trackExtension;
00555   double showerEnergy = fEventInfo.reco->showerEnergyNC;
00556 
00557   if(fEventInfo.header->detector == int(Detector::kNear)
00558      && fEventInfo.reco->isSimpleCutsClean< 1 ) return;
00559 
00560   dq[kDQEventLength-3]->Fill(fEventInfo.reco->eventLength, weight);
00561   dq[kDQNumTracks-3]->Fill(fEventInfo.reco->numberTracks, weight);
00562 
00563   if(fEventInfo.reco->numberTracks > 0
00564      && fEventInfo.reco->trackExtension > -9000.
00565      && showerEnergy > 0.0)
00566     dq[kDQTrackExtension-3]->Fill(trackExtension, weight);
00567 
00568 
00569   //  cout << "Weight: " << weight << endl
00570   //    << "eventLength: " << fEventInfo.reco->eventLength
00571   //    << " histo: " << dq[0]->GetBinContent(15) << endl
00572   //    << "NumTracks: " << fEventInfo.reco->numberTracks
00573   //    << " histo: " << dq[1]->GetBinContent(2) << endl
00574   //       << "TrackExtension: " << trackExtension  << "  " << showerEnergy
00575   //    << " histo: " << dq[2]->GetBinContent(30) << endl
00576   //    << endl;
00577 }
00578 
00579 //-----------------------------------------------------------------------
00580 //preparation for extrapolating Near to Far
00581 void NCExtrapolationModule::PrepareForExtrapolation()
00582 {
00583   MSG("NCExtrapolationModule", Msg::kInfo) << "PrepareForExtrapolation" << endl;
00584   //pass the module registry into the extrapolations to prepare them
00585   for(unsigned int i = 0; i < fExtrapolations.size(); ++i)
00586     fExtrapolations[i]->Prepare(fConfig);
00587 }
00588 
00589 
00590 //-----------------------------------------------------------------------
00591 //extrapolation step does all extrapolation algorithms at once
00592 //the farMC chain is the monte carlo for the far detector.
00593 //some extrapolations need to do stuff with the near first,
00594 //then use those results to apply to the far monte carlo events
00595 //for the prediction
00596 void NCExtrapolationModule::ExtrapolateNearToFar()
00597 {
00598   /*
00599   const bool loadingExtrapolations = fLoadExtrapolationsFile != "";
00600 
00601   // Ugh - should instead break this function down so we can select parts of it
00602   if(fLoadExtrapolationsFile != ""){
00603     for(unsigned int i = 0; i < fExtrapolations.size(); ++i){
00604       NC::FitMaster* fm = new NC::FitMaster(fExtrapolations[i]);
00605       fm->Prepare(fConfig);
00606       fm->Run(fTrueOscPars);
00607       fFitMasters.push_back(fm);
00608     }
00609     return;
00610   }
00611   */
00612 
00613   MSG("NCExtrapolationModule", Msg::kInfo) << "ExtrapolateNearToFar" << endl;
00614 
00615   //predict the far detector and make sure to combine any running conditions
00616   for(unsigned int i = 0; i < fExtrapolations.size(); ++i){
00617     fExtrapolations[i]->DoneFilling();
00618     NC::FitMaster* fm = new NC::FitMaster(fExtrapolations[i]);
00619     fm->Prepare(fConfig);
00620     fm->Run(fTrueOscPars);
00621     fFitMasters.push_back(fm);
00622   }
00623 }
00624 
00625 
00626 //-----------------------------------------------------------------------
00627 void NCExtrapolationModule::DoMockExperiments()
00628 {
00629   if(fMockExperimentsSeed == 0)
00630     MSG("NCExtrapolationModule", Msg::kWarning) << "DoMockExperiments: random seed not set, using default (0)" << endl;
00631 
00632 
00633   TRandom3 r;
00634 
00635   for(int n = 0; n < fNumMockExperiments; ++n){
00636     // Reset everyone's FD data
00637     for(unsigned int i = 0; i < fExtrapolations.size(); ++i)
00638       fExtrapolations[i]->Reset(false, true, false, false);
00639 
00640     r.SetSeed(fMockExperimentsSeed);
00641     r.SetSeed(n+r.Integer(UInt_t(-1)));
00642 
00643     for(unsigned int n = 0; n < fFDMCSample.size(); ++n){
00644       NCEventInfo* s = fFDMCSample[n];
00645       for(unsigned int i = 0; i < fExtrapolations.size(); ++i){
00646         double tmp_weight = s->reco->weight;
00647         s->reco->weight = r.Poisson(s->reco->weight);
00648         // Is this way faster?
00649         //      s->reco->weight = (s->reco->weight > r.Uniform()) ? 1 : 0;
00650 
00651         BeamType::BeamType_t beamType = (BeamType::BeamType_t)(fEventInfo.beam->beamType);
00652         NCBeam::Info beamInfo(beamType, NC::RunUtil::kRunI);
00653 
00654         if(s->reco->weight){
00655           fExtrapolations[i]->AddEvent(*s, true,
00656                                        NCType::kBeamFile, // TODO is kBeamFile right?
00657                                        beamInfo);
00658         }
00659         s->reco->weight = tmp_weight;
00660       }//end loop over extrapolation objects
00661     }
00662 
00663     for(unsigned int i = 0; i < fExtrapolations.size(); ++i){
00664       NCExtrapolation* extrap = fExtrapolations[i];
00665       //      extrap->CombineRuns(Detector::kFar);
00666       NC::FitMaster fm(extrap);
00667       Registry r = fConfig;
00668       // Counteract the "preciseParams" scaling normally done in the
00669       // initial fit. This is a bit ugly, would be better to disable the
00670       // scaling instead of fighting it.
00671 
00672       // Changed my mind, we need to be fair to the real fit
00673 
00674       //      r.UnLockValues();
00675       //      r.Set("PrecScale", 0.01);
00676 
00677       fm.Prepare(r);
00678 
00679       fm.SetFixedValuesForMarginalization(fTrueOscPars);
00680       fm.Run(0);
00681 
00682       const double trueChi = extrap->FindChiSqrForPars(fTrueOscPars,
00683                                                        NC::SystPars());
00684 
00685       // Slight problem here in that we don't distinguish which extrapolation
00686       // this result came from, so there's no way to tell in the output file.
00687       // Isn't a problem if you only run one extrapolation, which is the common
00688       // use case.
00689       Registry* reg = fm.GetBestFitPointAsRegistry();
00690       reg->Set("true_chisq", trueChi);
00691       fMockFits.push_back(reg);
00692     }
00693   }
00694 }
00695 
00696 
00697 //-----------------------------------------------------------------------
00698 void NCExtrapolationModule::
00699 SystematicsFromRegistry(bool* systematicsToUse,
00700                         vector<double>& systematicsAdjust)
00701 {
00702   //get the parameters to be altered
00703   int         tmpb;  // a temp bool. See comment under DefaultConfig...
00704   double      tmpd;  // a temp double.
00705 
00706   //set the defaults for the systematic parameters from the config
00707   //set the adjustment to be an actual value, the macro should have
00708   //passed in a number of sigma
00709 
00710   for(int i = 0; i < NCType::kNumSystematicParameters; ++i){
00711     if(fConfig.Get("ChangeMCAsData" + NCType::kParams[i].name, tmpb))
00712       systematicsToUse[i] = tmpb;
00713 
00714     if(fConfig.Get("Adjust" + NCType::kParams[i].name, tmpd))
00715       systematicsAdjust.push_back(NCType::kParams[i].defaultVal +
00716                                   tmpd*NCType::kParams[i].sigma);
00717 
00718     if(systematicsToUse[i]){
00719       MAXMSG("NCExtrapolationModule", Msg::kInfo, NCType::kNumSystematicParameters)
00720         << "Using MC As Data: "
00721         << NCType::kParams[i].name << " adjusted to "
00722         << systematicsAdjust[i] << endl;
00723     }
00724   }
00725 }
00726 
00727 
00728 //-----------------------------------------------------------------------
00729 void NCExtrapolationModule::ApplySystematicShifts(NC::RunUtil::ERunType runType)
00730 {
00731   static bool systematicsToUse[NCType::kNumSystematicParameters];
00732   static vector<double> systematicsAdjust;
00733 
00734   static bool once = true;
00735   if(once){
00736     once = false;
00737     SystematicsFromRegistry(systematicsToUse, systematicsAdjust);
00738   }
00739 
00740   // always use the nue values when finding the event weight because
00741   // the size of the nue contrib is passed in by the macro
00742   fEventInfo.SetEventWeight(systematicsToUse, systematicsAdjust,
00743                             fTrueOscPars, 0, runType, true, true);
00744 
00745   if(TMath::Abs(fEventInfo.reco->weight) < 5.e-2 &&
00746      fEventInfo.reco->weight < 0.)
00747     fEventInfo.reco->weight = 0.;
00748 }
00749 
00750 //-----------------------------------------------------------------------
00751 void NCExtrapolationModule::SetEnergies()
00752 {
00753   if(fEventInfo.analysis->isCC > 0){
00754     // The RHSs here *should* be reco and not reco_nom, because we
00755     // want the shifted value of (nu|shower)EnergyCC if it has been
00756     // shifted
00757     fEventInfo.reco->nuEnergy = fEventInfo.reco->nuEnergyCC;
00758     fEventInfo.reco->showerEnergy = fEventInfo.reco->showerEnergyCC;
00759 
00760     // We need to do this because (inter alia) the calculation of the
00761     // ND cleaning syst relies on showerEnergy being set to the right
00762     // one. We're safe from considerations of whether things have been
00763     // systematically shifted because reco_nom is never systematically
00764     // shifted
00765     fEventInfo.reco_nom->nuEnergy = fEventInfo.reco_nom->nuEnergyCC;
00766     fEventInfo.reco_nom->showerEnergy = fEventInfo.reco_nom->showerEnergyCC;
00767   }
00768   else if(fEventInfo.analysis->isNC > 0){
00769     fEventInfo.reco->nuEnergy = fEventInfo.reco->showerEnergyNC;
00770     fEventInfo.reco->showerEnergy = fEventInfo.reco->showerEnergyNC;
00771 
00772     // See comment above
00773     fEventInfo.reco_nom->nuEnergy = fEventInfo.reco_nom->nuEnergyNC;
00774     fEventInfo.reco_nom->showerEnergy = fEventInfo.reco_nom->showerEnergyNC;
00775 
00776     // (PAR) This used to be set here, but that breaks FindEventWeight
00777     // for NC events if we're using CC energy for those. But
00778     // NCExtrapolation::DrawBestFitSpectra relies on (shower+track)
00779     // giving the NC or CC energy appropriate to the classification,
00780     // so setting track energy to zero is now done in NCEnergyBin::AddEventToBin
00781     //fEventInfo.reco->muEnergy = 0.;
00782   }
00783 
00784   // Energies < 0 occur when there's no shower and we get a default value
00785   if(fEventInfo.reco->showerEnergy < 0.) fEventInfo.reco->showerEnergy = 0.;
00786 }
00787 
00788 //-----------------------------------------------------------------------
00789 double NCExtrapolationModule::GetMCScaleFactor(Detector::Detector_t det,
00790                                                NCType::EFileType fileType,
00791                                                NCBeam::Info info)
00792 {
00793   // Choose the appropriate pot maps for this event and scale
00794   // down the event to match the data POT.
00795   POTMap* potData=0;
00796   POTMap* potMC=0;
00797   switch(det){
00798   case Detector::kNear:
00799     potData=&fDataPOTNear;
00800     potMC=&fMCPOTNear;
00801     break;
00802   case Detector::kFar:
00803     potData=&fDataPOTFar;
00804     switch(fileType){
00805     case NCType::kTauFile:
00806       potMC=&fMCPOTFarTau;
00807       break;
00808     case NCType::kElectronFile:
00809       potMC=&fMCPOTFarElectron;
00810       break;
00811     default:
00812       potMC=&fMCPOTFar;
00813     }
00814     break;
00815   default:
00816     assert(0 && "Unknown detector. This shouldn't happen");
00817   }
00818 
00819   double tmp=GetScaleFactorFromMaps(*potData, *potMC, info);
00820   if(tmp>0) return tmp;
00821 
00822   // ...otherwise try to find the same beam with no syst shifts
00823   const vector<NCType::EFitParam> adj;
00824   const vector<double> vals;
00825   info.SetSystShifts(adj, vals);
00826 
00827   return GetScaleFactorFromMaps(*potData, *potMC, info);
00828 }
00829 
00830 //-----------------------------------------------------------------------
00831 double NCExtrapolationModule::GetScaleFactorFromMaps(POTMap& potData,
00832                                                      POTMap& potMC,
00833                                                      NCBeam::Info info)
00834 {
00835   // See if we actually found the beam in both...
00836   const bool foundData = potData.find(info) != potData.end();
00837   const bool foundMC = potMC.find(info) != potMC.end();
00838 
00839   // If we have data POTs for this beam, we'd better have some MC to go with it.
00840   if(foundData && !foundMC){
00841     MSG("NCExtrapolationModule", Msg::kError)
00842       << "Found data POT but not MC for " 
00843       << info << endl;
00844     
00845     MSG("NCExtrapolationModule", Msg::kError) << "Data POTs: " << endl;
00846     for(POTMap::iterator it=potData.begin(); it!=potData.end(); ++it)
00847       MSG("NCExtrapolationModule", Msg::kError)
00848         << it->first << ": " << it->second << endl;
00849     
00850     MSG("NCExtrapolationModule", Msg::kError) << "MC POTs: " << endl;
00851     for(POTMap::iterator it=potMC.begin(); it!=potMC.end(); ++it)
00852       MSG("NCExtrapolationModule", Msg::kError)
00853         << it->first << ": " << it->second << endl;
00854     exit(1);
00855   }
00856 
00857   // If we have no data, return 0;
00858   if(!foundData) return 0;
00859 
00860   // Otherwise return the actual scale factor
00861   return potData.find(info)->second/potMC.find(info)->second;
00862 }
00863 
00864 //-----------------------------------------------------------------------
00865 void NCExtrapolationModule::SetEventWeight(BeamType::BeamType_t beamType,
00866                                            NC::RunUtil::ERunType runType,
00867                                            bool fakeDataSet)
00868 {
00869   Detector::Detector_t det = Detector::Detector_t(fEventInfo.header->detector);
00870   SimFlag::SimFlag_t sim = SimFlag::SimFlag_t(fEventInfo.header->dataType);
00871   NCType::EFileType fileType = NCType::FindFileType(fEventInfo.header);
00872 
00873   // Data events don't get scaled or systematically shifted
00874   if(sim==SimFlag::kData){
00875     SetEnergies();
00876     return;
00877   }
00878   else if(sim==SimFlag::kMC){
00879     if(fakeDataSet){
00880       // This includes SKZP via NCEventInfo::GetEventWeight
00881       ApplySystematicShifts(runType);
00882     }
00883     else{
00884       // Just apply the SKZP weight
00885       fEventInfo.reco->weight=fEventInfo.GetSKZPWeight(runType);
00886     }
00887 
00888     const NCBeam::Info info=NCBeam::Info(beamType, runType);
00889     fEventInfo.reco->weight *= GetMCScaleFactor(det, fileType, info);
00890     // ApplySystematicShifts will (indirectly) have altered nuEnergy and
00891     // showerEnergy, so make sure they're set right
00892     SetEnergies();
00893   }
00894   else{
00895     assert(0 && "This shouldn't happen");
00896   }
00897 }
00898 
00899 //-----------------------------------------------------------------------
00900 bool NCExtrapolationModule::FinalEventCheck()
00901 {
00902   //check any final cuts here
00903   if(!fEventInfo.FinalEventCheck()
00904      && !fSingleSpectrum) return false;
00905 
00906   return fEventInfo.header->isGoodData;
00907 }
00908 
00909 
00910 //-----------------------------------------------------------------------
00911 void NCExtrapolationModule::CreateExtrapolations(TString extraps)
00912 {
00913   MSG("NCExtrapolationModule", Msg::kInfo) << "Registered extrapolations:\n";
00914 
00915   const vector<TString> extrapArgNames = NC::Utility::ParseStringList(extraps);
00916 
00917   for(unsigned int n = 0; n < GetExtrapolationFactories().size(); ++n){
00918     NCExtrapolationFactory* ex = GetExtrapolationFactories()[n];
00919     const TString codeName = ex->GetCodeName();
00920 
00921     MSG("NCExtrapolationModule", Msg::kInfo) << "  " << codeName << " - ";
00922 
00923     bool inExtraps = false;
00924     for(unsigned int i = 0; i < extrapArgNames.size(); ++i)
00925       if(extrapArgNames[i] == codeName) inExtraps = true;
00926 
00927     if(inExtraps){
00928       if(fLoadExtrapolationsFile != ""){
00929         MSG("NCExtrapolationModule", Msg::kInfo) << "Loading from file\n";
00930         TDirectory* curDir = gDirectory;
00931         TFile f(fLoadExtrapolationsFile);
00932         NCExtrapolation* e = (NCExtrapolation*)f.Get("NCExtrapolation"+codeName);
00933         assert(e);
00934         fExtrapolations.push_back(e);
00935         f.Close();
00936         curDir->cd();
00937         // Restoring data spectra from the file is not generally useful.
00938         if(!fIncludeDataFromLoadedExtrapolations)
00939           e->Reset(true, true, false, false);
00940       }
00941       else{
00942         MSG("NCExtrapolationModule", Msg::kInfo) << "Creating\n";
00943         fExtrapolations.push_back(ex->Create());
00944       } // end if fLoadExtrapolationsFile
00945     }
00946     else{
00947       MSG("NCExtrapolationModule", Msg::kInfo) << "Not creating\n";
00948     } // end if inExtraps
00949   } // end for n
00950 }
00951 
00952 
00953 //-----------------------------------------------------------------------
00954 void NCExtrapolationModule::AddEventToExtrapolations(bool fakeDataSet)
00955 {
00956   // This is pretty much immediately after the event comes off disk. Call
00957   // SetEnergies here, as early as possible, so showerEnergy and trackEnergy
00958   // are set to the right NC/CC variants. This is certainly needed for getting
00959   // systematic shifts right, and maybe other reasons.
00960   SetEnergies();
00961 
00962   SimFlag::SimFlag_t sim = SimFlag::SimFlag_t(fEventInfo.header->dataType);
00963 
00964   //Use PID custom selection cut if so desired
00965   if(fUsePIDCustomCut &&
00966      TMath::Abs(fPIDCustomCut-fEventInfo.analysis->separationParameterCut) > 1e-3){
00967     fEventInfo.analysis->separationParameterCut = fPIDCustomCut;
00968 
00969     fEventInfo.analysis->isNC = int(fEventInfo.analysis->separationParameter
00970                                     < fPIDCustomCut);
00971     fEventInfo.analysis->isCC = int(fEventInfo.analysis->separationParameter
00972                                     >= fPIDCustomCut);
00973   }
00974 
00975   //check for any extra cuts you may want to apply, eg good shower cut
00976   if(!FinalEventCheck()) return;
00977 
00978   //check if the event is from a tau file.
00979   const NCType::EFileType fileType = NCType::FindFileType(fEventInfo.header);
00980   const NC::RunUtil::ERunType runType  = NC::RunUtil::FindRunType(fEventInfo.header,
00981                                                                   fEventInfo.reco);
00982 
00983   if(fileType == NCType::kTauFile ||
00984      fileType == NCType::kElectronFile){
00985     //dont add in NC tau or nue appearance
00986     //events as you cant distinguish flavor
00987     //with NC events.  NCEnergyBin wouldnt
00988     //accept the event anyway.  also reject
00989     //events from these files that start off as
00990     //nue...just say they dont oscillate as
00991     //they dont contribute much anyway
00992     if(fEventInfo.truth->interactionType == NCType::kNC ||
00993        TMath::Abs(fEventInfo.truth->nonOscNuFlavor) == 12) return;
00994   }
00995   else if(fileType == NCType::kUnknownFile) return;
00996 
00997   // Single spectrum fitting
00998   if(fSingleSpectrum){
00999     fEventInfo.analysis->isNC = 0;
01000     fEventInfo.analysis->isCC = 1;
01001   }
01002 
01003 
01004   if(sim == SimFlag::kData || fileType == NCType::kMockFile)
01005     fEventInfo.truth = 0;
01006 
01007   // Mock data should have simflag set to data
01008   if (fileType == NCType::kMockFile)
01009     fEventInfo.header->dataType=SimFlag::kData;
01010 
01011   //--------------------------------------------------------------------------------
01012   //put in for testing purposes, should be commented out for real fits
01013   //if(TMath::Abs(fEventInfo.truth->nuFlavor) == 12) continue;
01014   //     fEventInfo.analysis->isNC = 0;
01015   //     fEventInfo.analysis->isCC = 0;
01016   //     if(fEventInfo.truth->interactionType < 1) fEventInfo.analysis->isNC = 1;
01017   //     else if(fEventInfo.truth->interactionType > 0) fEventInfo.analysis->isCC = 1;
01018   //     fEventInfo.reco->nuEnergy = truthInfo->nuEnergy;
01019   //--------------------------------------------------------------------------------
01020 
01021   // TODO - correct if statement?
01022   if(sim == SimFlag::kMC && fakeDataSet &&
01023      fEventInfo.header->detector == Detector::kFar &&
01024      fNumMockExperiments > 0){
01025     NCEventInfo* evt = new NCEventInfo;
01026     evt->DeepCopy(&fEventInfo);
01027 
01028     fFDMCSample.push_back(evt);
01029   }
01030 
01031   const BeamType::BeamType_t beamType =
01032     (BeamType::BeamType_t)(fEventInfo.beam->beamType);
01033   const NCBeam::Info beamInfo(beamType, runType);
01034   const NCBeam::Info infoAll(beamType, NC::RunUtil::kRunAll);
01035 
01036 
01037   //add event to each extrapolation
01038   for(unsigned int i = 0; i < fExtrapolations.size(); ++i){
01039     if(sim==SimFlag::kMC){
01040         SetEventWeight(beamType, runType, fakeDataSet);
01041 
01042         // If we have MC for this beam but not data, SetEventWeight
01043         // will have set the weight to zero, so don't add it at
01044         // all. This ensures that the MC beams that have events added
01045         // to them are the ones that were selected in the RunsToUse
01046         // registry key *and* have data available
01047         if(fEventInfo.reco->weight!=0){
01048           
01049           //NCBeam::Info info=NCBeam::Info(beamType, thisRunType);
01050           fExtrapolations[i]->AddEvent(fEventInfo, fakeDataSet,
01051                                        fileType, beamInfo);
01052           // Also add it to the RunAll beam
01053           fExtrapolations[i]->AddEvent(fEventInfo, fakeDataSet,
01054                                        fileType, infoAll);
01055           
01056           if(fShiftedBeams){
01057             AddShiftedEventToExtrapolations(fEventInfo, fakeDataSet, fileType,
01058                                             runType, beamInfo);
01059             AddShiftedEventToExtrapolations(fEventInfo, fakeDataSet, fileType,
01060                                             runType, infoAll);
01061           }
01062 
01063         }// end if non-zero weight
01064     }// end if MC
01065     else{
01066       SetEnergies();
01067       // Data/mock data goes in whatever run it really is...
01068       fExtrapolations[i]->AddEvent(fEventInfo, fakeDataSet,
01069                                    fileType, beamInfo);
01070       // ...and RunAll
01071       fExtrapolations[i]->AddEvent(fEventInfo, fakeDataSet,
01072                                    fileType, infoAll);
01073     }
01074   }//end loop over extrapolation objects
01075 
01076 
01077   if(fMakeDQPlotsSpecial){
01078     if(fEventInfo.header->dataType == int(SimFlag::kMC)){
01079       if(fEventInfo.header->detector == int(Detector::kNear)){
01080         FillDataQualityPlotsSpecial(fDQNearMCTotalSpecial, false);
01081       }
01082     }
01083   }
01084 }
01085 
01086 
01087 //-----------------------------------------------------------------------
01088 void NCExtrapolationModule::
01089 GetListOfShifts(vector<bool*>& useParameters,
01090                 vector<vector<double> >& adjustedValues) const
01091 {
01092   assert(useParameters.empty() && adjustedValues.empty());
01093 
01094   // This allows us to find out if a particular variable is in the fit
01095   NC::CoordinateConverter cc;
01096   cc.Prepare(fConfig, true);
01097 
01098   // First work out all the combinations of systematics we need. We use
01099   // every combination of nominal and plus/minus one sigma. ie we should
01100   // add each event 3^n-1 times (we don't do the completely nominal case)
01101 
01102   // We start with the nominal arrangement - ie no shifts enabled, and all
01103   // set to their default values
01104   useParameters.resize(1);
01105   adjustedValues.resize(1);
01106 
01107   useParameters[0] = new bool[NCType::kNumSystematicParameters];
01108   adjustedValues[0].resize(NCType::kNumSystematicParameters);
01109   for(int n = 0; n < NCType::kNumSystematicParameters; ++n){
01110     useParameters[0][n] = false;
01111     adjustedValues[0][n] = NCType::kParams[n].defaultVal;
01112   }
01113 
01114   // For every possible systematic
01115   for(unsigned int syst = 0; syst < NCType::kNumSystematicParameters; ++syst){
01116     // We check if we're fitting for it
01117     if(!cc.IsFit(NCType::EFitParam(syst))) continue;
01118 
01119     // and if so, duplicate all the configurations we have so far in two
01120     // more modes, for plus/minus one sigma in this new parameter.
01121 
01122     // If the option for simple shifted beams is on then we only base our
01123     // shifting on the nominal beam -> 2n shifted beams
01124     const unsigned int N = fSimpleShiftedBeams ? 1 : useParameters.size();
01125 
01126     for(unsigned int n = 0; n < N; ++n){
01127       bool* up = new bool[NCType::kNumSystematicParameters];
01128       for(int i = 0; i < NCType::kNumSystematicParameters; ++i)
01129         up[i] = useParameters[n][i];
01130 
01131       vector<double> av = adjustedValues[n];
01132       up[syst] = true;
01133       av[syst] -= NCType::kParams[syst].sigma;
01134       useParameters.push_back(up);
01135       adjustedValues.push_back(av);
01136 
01137       // Add twice the shift to cancel out the previous shift the other way
01138 
01139       av[syst] += 2*NCType::kParams[syst].sigma;
01140       useParameters.push_back(up);
01141       adjustedValues.push_back(av);
01142     }
01143   }
01144 
01145   // Remove the nominal case that we started with
01146   delete[] useParameters[0];
01147   useParameters.erase(useParameters.begin());
01148   adjustedValues.erase(adjustedValues.begin());
01149 
01150   // Check that we didn't lose track somewhere
01151   assert(useParameters.size() == adjustedValues.size());
01152 }
01153 
01154 
01155 //-----------------------------------------------------------------------
01156 void NCExtrapolationModule::
01157 AddShiftedEventToExtrapolations(NCEventInfo eventInfo,
01158                                 bool useMCAsData,
01159                                 NCType::EFileType fileType,
01160                                 NC::RunUtil::ERunType runType,
01161                                 NCBeam::Info beamInfo)
01162 {
01163   // No point adding/shifting data events
01164   if(eventInfo.header->dataType == NCType::kData || useMCAsData) return;
01165 
01166   Detector::Detector_t det = Detector::Detector_t(fEventInfo.header->detector);
01167   // On the assumption that the contents of the registry don't change between
01168   // successive calls to us, then save time by only working out what shifts
01169   // to do once.
01170   static vector<bool*> useParameters;
01171   static vector<vector<double> > adjustedValues;
01172   static bool once = true;
01173   if(once){
01174     once = false;
01175     GetListOfShifts(useParameters, adjustedValues);
01176   }
01177 
01178 
01179   NC::OscProb::OscPars* noosc = new NC::OscProb::NoOscillations;
01180 
01181   for(unsigned int i = 0; i < useParameters.size(); ++i){
01182     if(fSingleShiftedBeam >= 0 && int(i) != fSingleShiftedBeam) continue;
01183 
01184     static NCEventInfo backup; // Suspect that construction is expensive
01185 
01186     backup.DeepCopy(&eventInfo);
01187 
01188     fEventInfo = eventInfo;
01189 
01190     beamInfo.SetSystShifts(useParameters[i], &adjustedValues[i][0]);
01191 
01192     if(FinalEventCheck()){
01193       for(unsigned int j = 0; j < fExtrapolations.size(); ++j){
01194 
01195         // This function applies weight and syst shifts too to the
01196         // object (that it happens to ~ own)
01197         fEventInfo.SetEventWeight(useParameters[i], adjustedValues[i],
01198                                   noosc, 0, runType,
01199                                   true, false);
01200         fEventInfo.reco->weight *= GetMCScaleFactor(det, fileType, beamInfo);
01201         // SetEventWeight will (indirectly) have altered nuEnergy and
01202         // showerEnergy, so make sure they're set right
01203         SetEnergies();
01204         fExtrapolations[j]->AddEvent(eventInfo, useMCAsData, fileType, beamInfo);
01205       }
01206     }
01207 
01208     eventInfo.DeepCopy(&backup);
01209   } // end for i
01210 
01211   delete noosc;
01212 }
01213 
01214 
01215 //-----------------------------------------------------------------------
01216 std::vector<NCExtrapolationFactory*>& NCExtrapolationModule::
01217 GetExtrapolationFactories()
01218 {
01219   // Looks like we were falling foul of some variant of the
01220   // "static initialization order fiasco". Apply the workaround from
01221   // http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.13
01222   static std::vector<NCExtrapolationFactory*> facts;
01223   return facts;
01224 }

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