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

LZfluk.cxx

Go to the documentation of this file.
00001 // $Author: gmieg $ 
00002 //
00003 // $Revision: 1.3 $
00004 // 
00005 // $Name:  $
00006 //
00007 // $Id: LZfluk.cxx,v 1.3 2009/03/17 18:10:06 gmieg Exp $
00008 //
00009 // $Log: LZfluk.cxx,v $
00010 // Revision 1.3  2009/03/17 18:10:06  gmieg
00011 // #include <cstring> for strcmp.
00012 //
00013 // Revision 1.2  2009/03/08 19:30:07  loiacono
00014 // commit changes for Muon Fitting
00015 //
00016 // Revision 1.1  2009/02/15 14:23:27  loiacono
00017 // commit new classes for muon monitor fitting
00018 //
00019 // Revision 1.12  2008/03/15 17:23:31  zarko
00020 //
00021 // Renamed the old GetWeight functions in Zfluk to
00022 // GetWeightPRL and GetWeightBoston to avoid confusion between
00023 // different functional forms used for those fits.
00024 // Updated SKZPWeightCalculator to reflect the changes.
00025 //
00026 // Revision 1.11  2007/12/20 21:29:14  zarko
00027 // *** empty log message ***
00028 //
00029 // Revision 1.10  2007/03/03 21:27:05  zarko
00030 // Version used for PiMinus fits.
00031 //
00032 // Revision 1.9  2007/02/14 22:58:07  zarko
00033 // In this version of zfluk GetWeight(ptype,pt,pz) returns a weight using
00034 // 16 parameters (6 for pi+, 6 for K+, 2 for pi- and 2 for K-)
00035 //
00036 // Revision 1.8  2006/11/10 19:13:17  zarko
00037 // Changed the way kaon weights are calculated so that K/pi ratio is
00038 // preserved. Added K0L reweighting based on K+ and K- weights.
00039 // To get these weights use SetParameters(vector<double>) and
00040 // GetWeight(ptype, pT, pz) functions.
00041 //
00042 // Revision 1.7  2006/10/03 16:00:56  zarko
00043 // Updated code to reweight numus and numubars
00044 //
00045 // Revision 1.6  2006/06/02 04:37:53  zarko
00046 // Use arrays instead of histograms in GetPTshift to speed up the code.
00047 //
00048 // Revision 1.5  2006/04/14 02:37:31  zarko
00049 // Zfluk now looks into SRT_PUBLIC_CONTEXT if the data cannot be found in SRT_PRIVATE_CONTEXT
00050 //
00051 // Revision 1.4  2006/03/13 23:58:32  zarko
00052 // Updated SKZP parameterization. Now using 7 parameters.
00053 // One for kaons and 6 to parameterize pt-xf weights.
00054 //
00055 // Revision 1.3  2006/02/21 00:04:24  zarko
00056 // Modified Files:
00057 //      Zfluk.cxx Zfluk.h
00058 //
00059 // Added function GetPTshift(par). This uses the fluka05ptxf.root file that should
00060 // be in MCReweight/data. This function returns shift in mean pT for a given set
00061 // of parameters, for a parameterization that was set with UseParameterization.
00062 //
00063 // Revision 1.2  2006/01/30 20:57:56  zarko
00064 // Removed one parameter from SKZP (par[2])
00065 // Redefined par[3] (low pT) and par[4] (kaons) in SKZP,
00066 // and par[5] (kaons) in TV, so that they are just numbers.
00067 // They are not multiplicative factors of sigma distortions any more.
00068 //
00069 //
00070 
00071 #include "MCReweight/LZfluk.h"
00072 #include "MessageService/MsgService.h"
00073 #include "Registry/Registry.h"
00074 
00075 #include <string>
00076 #include <iostream>
00077 #include <cmath>
00078 #include <cstdlib>
00079 #include <cstring>
00080 #include <cassert>
00081 #include "TFile.h"
00082 #include "TH2F.h"
00083 #include "TSystem.h"
00084 ClassImp(LZfluk)
00085 
00086 CVSID("$Id: LZfluk.cxx,v 1.3 2009/03/17 18:10:06 gmieg Exp $");
00087 
00088 LZfluk::LZfluk(/*const char* dir*/) 
00089    :fPar(0),
00090     fWghtFromHist(true)
00091 {
00092 
00093 }
00094 
00095 //------------------------------------------------------------------------------------------
00096 void LZfluk::Init()
00097 {
00098    cout << "LZfluk::Init" << endl;
00099 
00100     std::string dir = "";
00101     TH1::AddDirectory(kFALSE);
00102    
00103   whichParameterization=0; //by default using SKZP parameterization
00104 
00105   // topDir is where the fluka05 pt-xf histogram file is
00106   std::string topDir=dir; // user may set location of input data
00107   if(topDir=="") { // by default, this code looks in a standard place
00108     topDir="MCReweight/data";
00109     std::string base="";
00110     base=getenv("SRT_PRIVATE_CONTEXT");
00111     if (base!="" && base!=".")
00112       {
00113         // check if directory exists in SRT_PRIVATE_CONTEXT
00114         std::string path = base + "/" + topDir;
00115         void *dir_ptr = gSystem -> OpenDirectory(path.c_str());
00116         if(!dir_ptr) base=getenv("SRT_PUBLIC_CONTEXT"); // if it doesn't exist then use SRT_PUBLIC_CONTEXT
00117         gSystem->FreeDirectory(dir_ptr);
00118       }
00119     else base=getenv("SRT_PUBLIC_CONTEXT");
00120     
00121     if(base=="") {
00122       MSG("MCReweight",Msg::kFatal)<<"No SRT_PUBLIC_CONTEXT set"<<std::endl;
00123       assert(false);
00124     }
00125     topDir = base+ "/" + topDir;
00126   }
00127 
00128   MSG("LZfluk",Msg::kDebug) <<"LZfluk reading data from: "<<topDir<<std::endl;
00129   std::string fileName =topDir+"/fluka05ptxf.root";
00130 
00131   TFile* hFile= 0;
00132 
00133   cout << "Opening ptxf file" << endl;
00134 
00135   hFile = new TFile(fileName.c_str());
00136 
00137   if(!hFile || !(hFile->IsOpen()))
00138   {
00139      hFile = new TFile("/minos/scratch/loiacono/Data/ForMonFit/fluka05ptxf.root", "READ");
00140      if(!hFile || !(hFile->IsOpen()))
00141      {
00142         cout << "Can't open /minos/scratch/loiacono/Data/ForMonFit/fluka05ptxf.root" << endl;
00143      }
00144   }
00145   
00146   fPlist.push_back(kPiPlus);
00147   fPlist.push_back(kPiMinus);
00148   fPlist.push_back(kKPlus);
00149   fPlist.push_back(kKMinus);
00150   fPlist.push_back(kK0L);
00151   
00152   for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();itPlist!=fPlist.end(); itPlist++)
00153     {
00154       TH2F* hist=dynamic_cast <TH2F*> (hFile->Get(Form("hF05ptxf%s",GetParticleName(*itPlist).c_str()))->Clone());
00155       hist->SetDirectory(0);
00156       TH2F* hist2=dynamic_cast <TH2F*> (hist->Clone(Form("hWeightedPTXF%s",GetParticleName(*itPlist).c_str())));
00157       hist2->SetDirectory(0);
00158       hist2->SetTitle(Form("%s weighted pt-pz",GetParticleName(*itPlist).c_str()));
00159 
00160       //const int nbinsx = hist -> GetNbinsX();
00161       const int nbinsx = 120;
00162       const int nbinsy = hist -> GetNbinsY();
00163       //cout << "nbinsx = " << nbinsx << "nbinsy = " << nbinsy << endl;
00164       //
00165       //The bins need to be the same as the bins that the pt-pz plots for the horn current scans!!!!!!!!!!!!!!!!!!!!!!!
00166       //
00167       fWeightHist[*itPlist] = new TH2D(Form("hWeightedPTXF%s",GetParticleName(*itPlist).c_str()),GetParticleName(*itPlist).c_str(), nbinsx, 0, 120, nbinsy, 0, 1);
00168       for(int ibinx = 0; ibinx <= nbinsx+1; ++ibinx)
00169       {
00170          for(int ibiny = 0; ibiny <= nbinsy+1; ++ibiny)
00171          {
00172             //cout << "ibinx = " << ibinx << "ibiny = " << ibiny << endl;
00173             fWeightHist[*itPlist] -> SetBinContent(ibinx, ibiny, 1.0);
00174          }
00175       }
00176       fWeightHist[*itPlist]->SetDirectory(0);
00177 
00178       std::pair<LZfluk::ParticleType_t, TH2F* > p(*itPlist, hist);
00179       std::pair<LZfluk::ParticleType_t, TH2F* > p2(*itPlist, hist2);
00180       fPTXF.insert(p);
00181       fWeightedPTXF.insert(p2);
00182 
00183       fPTXF[*itPlist]->SetDirectory(0);
00184       fWeightedPTXF[*itPlist]->SetDirectory(0);
00185 
00186       fMeanPT[*itPlist]=fPTXF[*itPlist]->ProjectionY()->GetMean()*1000.;
00187       fWeightedMeanPT[*itPlist]=fWeightedPTXF[*itPlist]->ProjectionY()->GetMean()*1000.;
00188             
00189       double N=fPTXF[*itPlist]->ProjectionY()->GetSumOfWeights();
00190       double wN=fWeightedPTXF[*itPlist]->ProjectionY()->GetSumOfWeights();
00191 
00192       fN[*itPlist]=N;
00193       fNWeighted[*itPlist]=wN;
00194     }
00195   hFile->Close();
00196   delete hFile;
00197   hFile=0;
00198 }
00199 
00200 LZfluk::~LZfluk() {
00201  for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();itPlist!=fPlist.end(); itPlist++)
00202     {
00203       delete fWeightHist[*itPlist];
00204       delete fPTXF[*itPlist];
00205       delete fWeightedPTXF[*itPlist];
00206     }
00207  fWeightHist.clear();
00208  fPTXF.clear();
00209  fWeightedPTXF.clear();
00210  fMeanPT.clear();
00211  fWeightedMeanPT.clear();
00212  fN.clear();
00213  fNWeighted.clear();
00214  fPlist.clear();
00215  fPar.clear();
00216  fNBinsX.clear();
00217  fNBinsY.clear();
00218 }
00219 
00220 //------------------------------------------------------------------------------------------
00221 void LZfluk::Config(const Registry &reg)
00222 {
00223 
00224    const char *value_char = 0;
00225 
00226    if(reg.Get("WGHTFROMHIST", value_char) && value_char)
00227    {
00228       if(std::strcmp(value_char, "no") == 0) 
00229       {
00230          fWghtFromHist = false;
00231       }
00232    }
00233 
00234         
00235    cout << "LZfluk::Config" << endl;
00236    cout << "   Get Weight From Hist = " <<  fWghtFromHist << endl;
00237    
00238    
00239 }
00240 
00241 //-------------------------------------------------------------------------------------
00242 double LZfluk::GetWeight(int ptype, double pT, double pz)
00243 {
00244     
00245    if(fWghtFromHist)
00246    {
00247       
00248       double weight = 1.0;
00249       
00250       LZfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00251       
00252       if(eptype != kPiPlus && eptype != kKPlus && eptype != kPiMinus && eptype != kPiMinus)
00253       {
00254          return 1.0;
00255       }
00256       
00257       if (pz > 120.0 || pz < 0.0 || pT < 0.0 || pT > 1.0)
00258       {
00259          return weight;
00260       }
00261       
00262       const int nbinsx = fWeightHist[eptype] -> GetNbinsX();
00263       const int nbinsy = fWeightHist[eptype] -> GetNbinsY();
00264       
00265       int binx = (fWeightHist[eptype] -> GetXaxis()) -> FindFixBin(pz);
00266       int biny = (fWeightHist[eptype] -> GetYaxis()) -> FindFixBin(pT);
00267       
00268       if(!(binx < 1) && !(biny < 1) && !(binx > nbinsx) && !(biny > nbinsy))
00269       {
00270          weight = fWeightHist[eptype] -> GetBinContent(binx, biny);
00271       }
00272       
00273       return weight;
00274    }
00275 
00276    else
00277    {
00278       return CalcWeight(ptype,pT,pz);
00279    }
00280    
00281 }
00282 
00283 //-------------------------------------------------------------------------------------
00284 double LZfluk::CalcWeight(int ptype, double pT, double pz)
00285 {
00286   double weight=1.;
00287 
00288   if (fPar.size()==0) 
00289     {
00290       MAXMSG("MCReweight",Msg::kWarning,10)
00291         <<"You need to set the parameters before calling "
00292         <<"LZfluk::CalcWeight (use SetParameters(vector<double>))"<<std::endl
00293         <<"Returning weight = "<<weight<<std::endl;
00294       return weight;
00295     }
00296 
00297   double xF=pz/120.;
00298   double A,B,C;
00299   double Ap,Bp,Cp;
00300   LZfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00301 
00302   // This is SKZP parameterization
00303   if (xF>1.||xF<0.) return weight;
00304   if (pT>1.||pT<0.) return weight;
00305 
00306   if (eptype==kPiPlus)
00307     {
00308       //Calculate weight for pions
00309       if (pT>=0.03)
00310         {
00311           // calculate the A, B and C in SKZP parameterization
00312           // A, B and C are best fit to Fluka 05
00313           
00314           A=-0.00761*pow((1.-xF),4.045)*(1.+9620.*xF)*pow(xF,-2.975);
00315           B=0.05465*pow((1.-xF),2.675)*(1.+69590.*xF)*pow(xF,-3.144);
00316           
00317           if (xF<0.22){
00318             C=-7.058/pow(xF,-0.1419)+9.188;
00319           }
00320           else{
00321             C = (3.008/exp((xF-0.1984)*3.577)) + 2.616*xF+0.1225;
00322           }
00323           
00324           // scale/skew A, B and C
00325           Ap=(fPar[0]+fPar[1]*xF)*A;
00326           Bp=(fPar[2]+fPar[3]*xF)*B;
00327           Cp=(fPar[4]+fPar[5]*xF)*C;
00328             
00329           weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00330         }
00331       else weight=CalcWeight(ptype,0.031,pz);  // for low pT
00332     }
00333   else if (eptype==kKPlus)
00334     {
00335       if (pT>=0.05)
00336         {
00337           // calculate the A, B and C in SKZP parameterization
00338           // A, B and C are best fit to Fluka 05
00339           
00340           A=-0.005187*pow((1.-xF),4.119)*(1.+2170.*xF)*pow(xF,-2.767);
00341           B=0.4918*pow((1.-xF),2.672)*(1.+1373.*xF)*pow(xF,-2.927);
00342           
00343           if (xF<0.22){
00344             C=-16.10/pow(xF,-0.04582)+17.92;
00345           }
00346           else{
00347             C = (6.905/exp((xF+0.163)*6.718)) - 0.4257*xF + 2.486;
00348           }
00349           
00350           // scale/skew A, B and C
00351           Ap=(fPar[6]+fPar[7]*xF)*A;
00352           Bp=(fPar[8]+fPar[9]*xF)*B;
00353           Cp=(fPar[10]+fPar[11]*xF)*C;
00354 
00355           weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00356         }
00357       else 
00358         weight=CalcWeight(ptype,0.051,pz);  // for low pT
00359     }
00360   else if (eptype==kPiMinus)
00361     {
00362       weight=CalcWeight(kPiPlus,pT,pz);
00363       if ( pz > 4. ) weight *= ( fPar[12] + fPar[13] * xF );
00364     }
00365   else if (eptype==kKMinus)
00366     {
00367       weight=CalcWeight(kKPlus,pT,pz)*(fPar[14]+fPar[15]*xF);
00368     }
00369   else if (eptype==kK0L)
00370     {
00371       //N(K0L) approximately given with (N(K+)+3*N(K-))/4
00372       weight= ((fNWeighted[kKPlus]+3.*fNWeighted[kKMinus])
00373                /(fN[kKPlus]+3.*fN[kKMinus]));
00374     }
00375   if (weight>10.) weight=10.;
00376   return weight;
00377 }
00378 
00379 //-------------------------------------------------------------------------------------
00380 void LZfluk::RecalculateWeights()
00381 {
00382   
00383   for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();
00384        itPlist!=fPlist.end(); itPlist++)
00385   {
00386      double xf,pt;
00387      double meanpt(0.);
00388      double sum(0.);
00389      const int nbinsx = fPTXF[*itPlist]->GetNbinsX();
00390      const int nbinsy = fPTXF[*itPlist]->GetNbinsY();
00391      for (int i=0;i<=nbinsx+1;i++)
00392      {
00393         for (int j=0;j<=nbinsy+1;j++)
00394         {
00395            xf=fPTXF[*itPlist]->GetXaxis()->GetBinCenter(i);
00396            pt=fPTXF[*itPlist]->GetYaxis()->GetBinCenter(j);
00397            double weight = CalcWeight(*itPlist,pt,xf);
00398            
00399            fWeightedPTXF[*itPlist]
00400               ->SetBinContent(i,j,(fPTXF[*itPlist]->GetBinContent(i,j)
00401                                    *weight));
00402 
00403            
00404            fWeightHist[*itPlist]->SetBinContent(i,j,weight);
00405            if(weight - fWeightHist[*itPlist]->GetBinContent(i,j) != 0)
00406            {
00407               LZfluk::ParticleType_t eptype= *itPlist;
00408               string name = GetParticleName(eptype);
00409               cout << "LZfluk::RecalculateWeights(): name = " << name << " pz = " << xf << " pt = " << pt
00410                    << " weight from calc = " << setprecision(10) << weight << " weight from hist = "
00411                    << fWeightHist[*itPlist]->GetBinContent(i,j)
00412                       << " diff = " << weight - fWeightHist[*itPlist]->GetBinContent(i,j) << endl;
00413            }
00414            
00415            //
00416            // Projection DOES include overflow bins
00417            // Get Mean DOES NOT
00418            //
00419            //need to include the overflow in y for sure in fWeightedPTXF
00420            //because it is used in the ratios below
00421            //but in meanpt we don't want to use this bin
00422            //I have checked that the fluka "signal" in i=nbinsx+1 is always 0
00423            //so it doesn't matter if this bin is included or not. I think the
00424            //proper thing is that is should be because the projection does
00425            //include it
00426            //
00427            if(j == nbinsy+1) continue;
00428            meanpt+=fWeightedPTXF[*itPlist]->GetBinContent(i,j)*pt;
00429            sum+=fWeightedPTXF[*itPlist]->GetBinContent(i,j);
00430            
00431 
00432         }
00433      }
00434      meanpt/=sum;
00435      fWeightedMeanPT[*itPlist]=meanpt*1000.; //GeV to MeV
00436      fNWeighted[*itPlist]=sum;
00437      meanpt=0.;
00438      sum=0.;
00439      
00440      
00441   }
00442 }
00443 
00444 //-------------------------------------------------------------------------------------
00445 double LZfluk::GetPTshift(int ptype, double pz_low, double pz_up)
00446 {
00447   //returns the pT shift for ptype particle due to reweighting in xf slice
00448   //given by pz_low and pz_up
00449   //this function returns correct ptshift only if the parameters were set using SetParameters
00450 
00451   LZfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00452 
00453   if (fPTXF.find(eptype)==fPTXF.end())
00454     {
00455       return 0.;
00456     }
00457   if (pz_low==0.&&pz_up==120.) return fWeightedMeanPT[eptype]-fMeanPT[eptype];
00458  
00459   int xlow=int(pz_low+1.);
00460   int xup=int(pz_up+1.);
00461  
00462   double pt;
00463   double meanpt(0.);
00464   double sum(0.);
00465   for (int i=xlow;i<xup;i++)
00466     {
00467       for (int j=1;j<51;j++)
00468         {
00469           pt=0.02*j-0.01;
00470           meanpt+=fWeightedPTXF[eptype]->GetBinContent(i,j)*pt;
00471           sum+=fWeightedPTXF[eptype]->GetBinContent(i,j);
00472         }
00473     }
00474   meanpt/=sum;
00475   meanpt*=1000.;  //GeV to MeV
00476 
00477   return meanpt-fMeanPT[eptype];
00478 
00479 }
00480 
00481 //-------------------------------------------------------------------------------------
00482 double LZfluk::GetNFrac(int ptype, double pz_low, double pz_up, double pt_low, double pt_up)
00483 {
00484   //returns the fractional change in number of particles due to reweighting in xf-pt region 
00485   //given by pz_low, pz_up and pt_low, pt_up
00486   
00487   LZfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00488   if (fPTXF.find(eptype)==fPTXF.end())
00489     {
00490       return 1.;
00491     }
00492   int xlow=int(pz_low+1.);
00493   int xup=int(pz_up+1.);
00494   int ylow=int(50.*pt_low+1.);
00495   int yup=int(50.*pt_up+1.);
00496   
00497   double wsum(0.);
00498   double sum(0.);
00499   for (int i=xlow;i<xup;i++)
00500     {
00501       for (int j=ylow;j<yup;j++)
00502         {
00503           sum+=fPTXF[eptype]->GetBinContent(i,j);
00504           wsum+=fWeightedPTXF[eptype]->GetBinContent(i,j);
00505         }
00506     }
00507 
00508   return wsum/sum;
00509 }
00510 
00511 //-------------------------------------------------------------------------------------
00512 std::string LZfluk::GetParticleName(LZfluk::ParticleType_t ptype)
00513 {
00514 switch (ptype)
00515    {
00516    case kPiPlus:          return "PiPlus";    break;
00517    case kPiMinus:         return "PiMinus";   break;
00518    case kKPlus:           return "KPlus";     break;
00519    case kKMinus:          return "KMinus";    break;
00520    case kK0L:             return "K0L";       break;
00521    case kUnknown:         return "Unknown";   break;
00522    default:               return "Unknown";   break;
00523    }
00524  
00525    return "Unknown";
00526 }
00527 
00528 //-------------------------------------------------------------------------------------
00529 LZfluk::ParticleType_t LZfluk::GetParticleEnum(int ptype)
00530 {
00531   switch (ptype)
00532     {
00533     case 8   :       return kPiPlus;      break;
00534     case 211 :       return kPiPlus;      break;    
00535     case 9   :       return kPiMinus;     break;
00536     case -211:       return kPiMinus;     break;
00537     case 11  :       return kKPlus;       break;
00538     case 321 :       return kKPlus;       break;
00539     case 12  :       return kKMinus;      break;
00540     case -321:       return kKMinus;      break;
00541     case 10  :       return kK0L;         break;
00542     case 130 :       return kK0L;         break;
00543     default:         return kUnknown;     break;
00544     }
00545   return kUnknown;
00546 
00547 }

Generated on Mon Feb 15 11:06:53 2010 for loon by  doxygen 1.3.9.1