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

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