00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021 #include "MCReweight/BeamEnergyCalculator.h"
00022 #include <cmath>
00023
00024 #include <ctype.h>
00025 #include <cassert>
00026 #include <utility>
00027 #include <iterator>
00028 #include <iostream>
00029
00030 #include "TH1.h"
00031 #include "TFile.h"
00032 #include "TSystem.h"
00033
00034 #include "Registry/Registry.h"
00035 #include "MCReweight/MCEventInfo.h"
00036 #include "MCReweight/NuParent.h"
00037 #include "MessageService/MsgService.h"
00038
00039
00040 CVSID("$Id: BeamEnergyCalculator.cxx,v 1.6 2007/01/30 03:13:14 rhatcher Exp $");
00041 const double BeamEnergyCalculator::low_energy_cut=1e-6;
00042
00043 BeamEnergyCalculator::BeamEnergyCalculator(Registry* stdconfig)
00044 :
00045 WeightCalculator(stdconfig),
00046 fFluxDir(0),fFluxFileName(""),
00047 fFluxFileChanged(true),
00048 fDetector(Detector::kUnknown),
00049 fBeam(BeamType::kUnknown),
00050 fLowRange(low_energy_cut), fHighRange(120.0),fCache()
00051 {
00052 fWCname="BeamEnergyCalculator";
00053 fStandardConfigChanged=true;
00054 Config();
00055 }
00056
00057
00058 void BeamEnergyCalculator::Config() {
00059 MSG("BEC", Msg::kInfo)<<"configuring..."<<endl;
00060
00061 int tempi=-1;
00062 double tempd=0.0;
00063 std::string ff;
00064 if(fStandardConfigChanged){
00065
00066 const char* c=fStandardConfig->GetCharString("beam:flux_file");
00067 if(c){
00068 ff=c;
00069 if(ff!=fFluxFileName){
00070 fFluxFileName=ff;
00071 fFluxFileChanged=true;
00072 }
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 if(fStandardConfig->Get("beam:beam_type",tempi)){
00084 fBeam=static_cast<BeamType::BeamType_t>(tempi);
00085 }
00086 if(fStandardConfig->Get("beam:detector",tempi)){
00087 fDetector=static_cast<Detector::Detector_t>(tempi);
00088 }
00089 if(fStandardConfig->Get("beam:low_energy_limit",tempd)){
00090 fLowRange=tempd;
00091 }
00092 if(fStandardConfig->Get("beam:high_energy_limit",tempd)){
00093 fHighRange=tempd;
00094 }
00095
00096 fStandardConfigChanged=0;
00097 }
00098
00099 }
00100
00101 void BeamEnergyCalculator::ReweightConfigReset(){
00102 if(fStandardConfig) SetReweightConfig(fStandardConfig);
00103 }
00104
00105
00106 double BeamEnergyCalculator::GetWeight(Registry* r){
00107
00108 BeamType::BeamType_t bt=BeamType::kUnknown;
00109 Detector::Detector_t det = Detector::kUnknown;
00110 int nu_idhep=0;
00111 double nu_energy=0;
00112 double high=0;
00113 double low=0;
00114 double w=1.0;
00115
00116
00117 bool bad=false;
00118 if(!r->Get("beam:nu_id",nu_idhep)) bad=true;
00119 if(!r->Get("beam:nu_energy",nu_energy)) bad=true;
00120
00121 if(bad){
00122 MSG("BEC", Msg::kFatal)<<"neutrino id or energy not set"<<endl;
00123 assert(0);
00124 }
00125
00126
00127 int tmpi=0;
00128 if(!r->Get("beam:beam_type",tmpi)){
00129
00130 bt=fBeam;
00131 }
00132 else{
00133 bt=static_cast<BeamType::BeamType_t>(tmpi);
00134 }
00135
00136 if(!r->Get("beam:detector",tmpi)){
00137
00138 det=fDetector;
00139 }
00140 else{
00141 det=static_cast<Detector::Detector_t>(tmpi);
00142 }
00143 if(!r->Get("beam:high_energy_limit",high)){
00144
00145 high=fHighRange;
00146 }
00147 if(!r->Get("beam:low_energy_limit",low)){
00148
00149 low=fLowRange;
00150 }
00151
00152 w=GetWeight(bt,det,nu_idhep,nu_energy,high,low);
00153
00154 return w;
00155 }
00156 double BeamEnergyCalculator::GetWeight(MCEventInfo* ,
00157 NuParent* ){
00158 MSG("BEC", Msg::kFatal)<<"Function Not Implemented Yet!"<<endl;
00159 assert(0);
00160 return 1;
00161 }
00162
00163
00164 double BeamEnergyCalculator::GetWeight(BeamType::BeamType_t bt,
00165 Detector::Detector_t det,
00166 int nu_idhep, double nu_energy,
00167 double high_energy_limit,
00168 double low_energy_limit){
00169 double w=0.0;
00170 if(bt==BeamType::kInverseE){
00171
00172 w=DeriveInverseEWeight(nu_energy,high_energy_limit, low_energy_limit);
00173 }
00174 else if(bt==BeamType::kUnknown){
00175 MSG("BEC", Msg::kFatal)<<"Requested weight for unknown beam type"<<endl;
00176 assert(0);
00177 }
00178 else{
00179 TH1* h = GetHist(bt,det,nu_idhep);
00180
00181 if(!h) {w=1.0; return w;}
00182
00183 w=DeriveWeight(h,nu_energy,high_energy_limit,low_energy_limit);
00184 }
00185
00186 return w;
00187 }
00188
00189 double BeamEnergyCalculator::DeriveWeight(TH1* h,double energy,
00190 double high, double low){
00191
00192
00193
00194 if(energy>high || energy<low) return 0;
00195 if(!h) return 0;
00196 if(low<low_energy_cut) low=low_energy_cut;
00197 Double_t* integral=h->GetIntegral();
00198 if(!integral){ h->ComputeIntegral(); integral=h->GetIntegral();}
00199 Int_t binlow=h->FindBin(low);
00200 Int_t binhigh=h->FindBin(high);
00201 if(binlow<1 || binhigh>h->GetNbinsX()) return 0;
00202 Int_t bin = h->FindBin(energy);
00203 double weight = h->GetBinContent(bin);
00204 double norm = integral[binhigh]-integral[binlow-1];
00205 Stat_t stats[4];
00206 h->GetStats(stats);
00207 Stat_t sumw=stats[0];
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 if(norm<=0) {
00221 MSG("BEC",Msg::kFatal)<<"normalization=0"<<endl;
00222 assert(0);
00223 }
00224
00225 weight/=(norm*sumw);
00226
00227 return weight;
00228 }
00229
00230
00231 double BeamEnergyCalculator::DeriveInverseEWeight(double energy,
00232 double high,double low){
00233
00234
00235 if(low<low_energy_cut) low = low_energy_cut;
00236 if(energy<low || energy>high) return 0;
00237 return (1/energy)/std::log(high/low);
00238
00239 }
00240
00241 void BeamEnergyCalculator::ConstructName(Detector::Detector_t det,
00242 int nu_idhep, std::string& s){
00243
00244
00245
00246
00247 using std::string;
00248 string nu;
00249 switch(nu_idhep){
00250 case 12: nu="nue"; break;
00251 case -12: nu="nuebar"; break;
00252 case 14: nu="numu"; break;
00253 case -14: nu="numubar"; break;
00254 case 16: nu="nutau"; break;
00255 case -16: nu="nutaubar"; break;
00256 default: nu="???"; break;
00257 }
00258 string dets=Detector::AsString(det);
00259 for(string::size_type i=0; i<dets.size(); i++){
00260 dets[i]=std::tolower(dets[i]);
00261 }
00262
00263 s+=dets+'_'+nu;
00264
00265 }
00266
00267 TH1* BeamEnergyCalculator::GetHist(BeamType::BeamType_t bt,
00268 Detector::Detector_t det,
00269 int nu_idhep){
00270
00271
00272
00273
00274
00275 if(fFluxFileChanged){
00276
00277 if(fFluxDir){
00278 delete fFluxDir; fFluxDir=0;
00279 }
00280 fCache.clear();
00281 MSG("BEC",Msg::kInfo)<<"opening new flux file: "
00282 <<fFluxFileName<<endl;
00283
00284 if(gSystem->AccessPathName(fFluxFileName.c_str()) == kTRUE){
00285
00286 MSG("BEC",Msg::kFatal)<<"cannot find flux file: "
00287 <<fFluxFileName<<endl;
00288 assert(0);
00289 }
00290 else{
00291 fFluxDir = new TFile(fFluxFileName.c_str());
00292 MSG("BEC",Msg::kInfo)<<"successfully opened: "
00293 <<fFluxFileName<<endl;
00294 }
00295 fFluxFileChanged=false;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 TH1* h = 0;
00307
00308
00309
00310 std::string s=BeamType::AsTag(bt);
00311
00312
00313
00314 s+="/flux_";
00315 ConstructName(det,nu_idhep,s);
00316
00317
00318
00319
00320 CacheMapIter it = fCache.find(s);
00321 if(it!=fCache.end()){
00322 h=it->second;
00323 }
00324 else{
00325
00326
00327 h = dynamic_cast<TH1*>(fFluxDir->Get(s.c_str()));
00328 if(h){
00329
00330 fCache.insert(std::pair<std::string,TH1*>(s,h));
00331 }
00332 else{
00333 MAXMSG("BEC",Msg::kWarning,10)
00334 <<"Could not find a flux histogram with the tag: "
00335 <<s<<"\n It's possible to continue but"
00336 <<" these events will not be weighted properly."<<endl;
00337 }
00338 }
00339 return h;
00340 }