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

DataUtil/EnergyCorrections.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // EnergyCorrections.h
00004 //
00005 // Corrections to energy based quantities
00006 //
00007 // Created:  M. Kordosky -- December, 2005
00008 //
00009 // $Author: xbhuang $
00010 //
00011 // $Revision: 1.25 $
00012 //
00013 // $Name:  $
00014 //
00015 // $Id: EnergyCorrections.cxx,v 1.25 2009/12/02 15:07:14 xbhuang Exp $
00016 //
00017 // $Log: EnergyCorrections.cxx,v $
00018 // Revision 1.25  2009/12/02 15:07:14  xbhuang
00019 // Include the fudge factor (1.0000) for the Dogwood1 calibration.
00020 //
00021 // Revision 1.24  2009/08/05 16:09:40  xbhuang
00022 //
00023 // Modified in order to add corrections for the Dogwood0 reconstruction.
00024 //
00025 // Revision 1.23  2009/07/22 17:48:33  xbhuang
00026 //
00027 // The far detector shower energy tuning function for Dogwood has been updated.
00028 //
00029 // Revision 1.22  2009/07/04 01:53:52  rhatcher
00030 // Remove tabs (replaced w/ spaces per coding conventions).  Did a bit of
00031 // other coding convention cleanup, but there is still a lot of ugliness
00032 // about the formatting that makes the code very hard to read.
00033 //
00034 // Revision 1.21  2009/07/03 14:12:39  xbhuang
00035 //
00036 // Defined 4 functions to do CC shower energy correction for Dogwood reconstruction.
00037 //
00038 // Revision 1.20  2007/12/21 15:36:08  rjn
00039 // Added switch for the ability to go back to the May version of the Masaki conversion
00040 //
00041 // Revision 1.19  2007/12/21 11:12:32  rjn
00042 // Added a WeightedShowerEnergyConversionDogwood function
00043 //
00044 // Revision 1.18  2007/12/19 16:39:48  rjn
00045 // Added Masaki's correction from DocDB 3895_v4
00046 //
00047 // Revision 1.17  2007/11/16 11:43:21  rjn
00048 // Added ShowerEnergyConversionDogwood which is the function to be called by CandShowerHandle to apply ourbest knowledge of the conversion from MEU to GeV for the dogwood reconstruction, such that to first order the GeV number in the tree is correct (until we know more at least).
00049 //
00050 // Revision 1.16  2007/11/11 06:41:26  rhatcher
00051 // Part of the ongoing purge of "DetectorType" in favor of "Detector"
00052 // (the former is a synonym of the latter ...)
00053 //
00054 // Revision 1.15  2007/10/09 14:25:52  hartnell
00055 //
00056 // One of the useful new messages was missing a "new line" at the end of it.
00057 //
00058 // Revision 1.14  2007/09/28 17:37:10  rjn
00059 // Adding the latest version of EnergyCorrections to the repository. I'm sure this is going to upset somebody, but then again it always does.
00060 //
00061 // Revision 1.13  2007/06/22 12:38:12  rjn
00062 // Hack for Release Type problem. The auto generated release types do not pick up the reconstruction sub versions at present
00063 //
00064 // Revision 1.12  2007/06/04 18:28:23  rjn
00065 // The preliminary version of the Calibration Group final MEU scale fudge factors are now available.
00066 //
00067 // Things to note for those users who are only interested in calibrating shower energy scale for the CC analysis, you can use the FullyCorrectShowerEnergy function, to apply both Calibration Group corrections and Masaki's shower energy tuning. Note that it is very important that you get the release type correct, for the analysis you should be using:
00068 // Data -- Cedar_phy
00069 // MC -- Cedar R1.24.1
00070 // These are the only data sets for which calibration numbers are provided.
00071 //
00072 //
00073 // If you are interested in making data or MC plots in fully calibrated MEU numbers you can use the CalibrationGroupEnergyCorrections function. This will convert MEU's from the sntp into fully calibrated MEU's. NB: It is very inmportant to be careful not to apply the corrections twice by calling both CalibrationGroupEnergyCorrections and FullyCorrectShowerEnergy. If you wish to do this investigate the WhichCorrection_t options and particular the kNoCalGroup option.
00074 //
00075 // Revision 1.11  2007/05/21 09:55:48  rjn
00076 // Just a tidying up sort of commit. Moved the Calibration Group corrections from the obliquely named CorrectionsForMasaki to the rather easier to understand EnergyCorrections::CalibrationGroupEnergyCorrections. NB: This function is called automatically by FullyCorrectShowerEnergy, so do not pass already corrected values to FullyCorrectShowerEnergy.
00077 //
00078 // Revision 1.10  2007/05/19 12:18:39  rjn
00079 // Added to the FullyCorrect family of EnergyCorrections. Now have corrections for shower energy and track momentum/energy from range. At this point users are encouraged to use these. There will still be a few under the hood changes but at this point I think there is a workable interface.
00080 //
00081 // Revision 1.9  2007/05/18 16:24:54  rjn
00082 // Added FullyCorrectShowerEnergy function that should replaces the previously used shower energy corrections. Should work with birch and cedar. It also applies the appropriate calibration group corrections. Everyone should use this who used any of the previous functions.
00083 //
00084 // Revision 1.8  2007/03/16 19:48:41  kordosky
00085 // Energy corrections for the FD!
00086 //
00087 // Revision 1.7  2007/03/13 16:36:15  kordosky
00088 // Energy Corrections for Cedar reconstruction
00089 // ND ONLY!!!
00090 // See 2785-v1 for the correction and 2767 for a description of the work (done by Masaki).
00091 //
00092 // Revision 1.6  2007/02/01 20:06:50  ishi
00093 // Semicolons at the end of namespace{} were removed.
00094 //
00095 // Revision 1.5  2007/02/01 17:47:33  kordosky
00096 // New version of EnergyCorrections. EnergyCorrections is now a namespace and calling code should invoke "using namespace EnergyCorrections". This is not expected
00097 // to cause problems since in the previous version all the correction functions were at global scope. Indeed, code including EnergyCorrections.h have been modified. Will handle cedar and birch by using static variables fVersion and fSubVersion, modified via SetCorrectionVersion(). Users need to do this, perhaps in their job macro. So far there is only one correction of each type and fSubVersion should be held at the default 0. Also, note the utility VersionFromFilename().
00098 //
00099 // Revision 1.4  2006/02/15 15:57:29  kordosky
00100 // add correction from for momentum via curvature as advocated in 1430-v2. Only modifies momenta of positively charged tracks.
00101 //
00102 // Revision 1.3  2006/02/13 00:20:02  kordosky
00103 // correction of +1.8% to FD data shower energy
00104 //
00105 // Revision 1.2  2006/02/12 22:09:58  kordosky
00106 // Update momentum correction to account for new density and thickness measurements.
00107 //
00108 // Revision 1.1  2005/12/16 03:38:51  kordosky
00109 // place implementation in a cxx file
00110 //
00111 // Revision 1.4  2005/12/16 02:52:43  kordosky
00112 // Forgot the include guards.  Thansk Niki.
00113 //
00114 // Revision 1.3  2005/12/15 22:44:31  kordosky
00115 // retweaked A Culling formulae in reaction to his presentation this morning
00116 //
00117 // Revision 1.2  2005/12/15 22:26:19  kordosky
00118 // E=sqrt(p*p+m*m)  != p   (almost negligible)
00119 //
00120 // Revision 1.1  2005/12/15 21:57:09  kordosky
00121 // moved from Mad
00122 //
00123 // Revision 1.2  2005/12/14 20:35:59  kordosky
00124 // Updated energy corrections.
00125 //
00126 // Revision 1.1  2005/12/13 19:41:35  kordosky
00127 // Standalone routines to correct the momentum via range to to groom et al range tables. Also, correct data to 7.755 g/cc which is our current best estimate of the detector density.
00128 //
00129 
00130 #include "DataUtil/EnergyCorrections.h"
00131 //#include "DataUtil/CalibratedShowerEnergy.h"
00132 #include "Calibrator/Calibrator.h"
00133 #include "MessageService/MsgService.h"
00134 #include <cmath>
00135 #include <iostream>
00136 #include <sstream>
00137 
00138 CVSID( " $Id: EnergyCorrections.cxx,v 1.25 2009/12/02 15:07:14 xbhuang Exp $");
00139 
00140 
00141 
00142 // Shower Energy Correction
00143 // ==========================
00144 //
00145 // All users are recommended to use the FullyCorrectShowerEnergy function to
00146 // apply corrections to shower energy. This function can be used for all
00147 // shower types and performs Calibration Group + other corrections. NB:
00148 // one now needs access to the offline database to call this function.
00149 //
00180 
00181 // New era of time dependent energy corrections
00182 float EnergyCorrections::FullyCorrectShowerEnergy(float E,// Input calorimetric shower energy in GeV
00183                                                   const CandShowerHandle::ShowerType_t& st, //Weighted not supported
00184                                                   VldContext vc, //Context of this specific event
00185                                                   ReleaseType::Release_t release, // Release version of the batch processing
00186                                                   EnergyCorrections::WhichCorrection_t whichCor)
00187 {
00188 
00189   //First step is to apply Calibration Group Corrections
00190   float eCor=EnergyCorrections::CalibrationGroupEnergyCorrections(E,vc,release,whichCor);
00191 
00192   // Get the reconstruction version.
00193   ReleaseType::Release_t recoVers = ReleaseType::GetRecoInfo(release);
00194 
00195   //Now need to apply Masaki's correction
00196   if (ReleaseType::IsBirch(release)) {
00197     int mode=1;
00198     if (whichCor==EnergyCorrections::kVersion2)
00199       mode=2;
00200     if (vc.GetDetector()==Detector::kNear)
00201       return EnergyCorrections::CorrectShowerEnergyNear_Birch(eCor,st,mode);
00202      else if (vc.GetDetector()==Detector::kFar)
00203        return EnergyCorrections::CorrectShowerEnergyFar_Birch(eCor,st,mode);
00204 
00205   }
00206   else if (ReleaseType::IsCedar(release)) {
00207     //Now need to check version
00208     if (recoVers >= ReleaseType::kR1_24_3) {
00209       if (vc.GetDetector()==Detector::kNear)
00210     return EnergyCorrections::ShowerEnergyCorrectionNearCedarPhyBhcurve(eCor,st,whichCor);
00211       else if (vc.GetDetector()==Detector::kFar)
00212     return EnergyCorrections::ShowerEnergyCorrectionFarCedarPhyBhcurve(eCor,st,whichCor);
00213 
00214     }
00215     else {
00216       if (vc.GetDetector()==Detector::kNear)
00217     return EnergyCorrections::ShowerEnergyCorrectionNearCedar(eCor,st,whichCor);
00218       else if (vc.GetDetector()==Detector::kFar)
00219     return EnergyCorrections::ShowerEnergyCorrectionFarCedar(eCor,st,whichCor);
00220     }
00221 
00222   }
00223   else if (ReleaseType::IsDogwood(release)) {
00224     if (vc.GetDetector()==Detector::kNear)
00225       return EnergyCorrections::ShowerEnergyCorrectionNearDogwood(eCor,st,whichCor);
00226     else if (vc.GetDetector()==Detector::kFar)
00227       return EnergyCorrections::ShowerEnergyCorrectionFarDogwood(eCor,st,whichCor);
00228   }
00229 
00230   return E;
00231 }
00232 
00233 
00234 
00236 //
00237 // All users are recommended to use the FullyCorrect family of track functions
00238 // apply corrections to track momentum/energy.
00239 //
00248 //The following routines should be used to correct track energy
00249 //and momentum.
00250 float EnergyCorrections::FullyCorrectMomentumFromRange(float p, //Momentum from range
00251                                                        VldContext vc, //Context of this specific event
00252                                                        ReleaseType::Release_t release, //Release verion of the batch processing
00253                                                        EnergyCorrections::WhichCorrection_t whichCor)
00254 {
00255    float pcor=p;
00256    if (ReleaseType::IsBirch(release)) {
00257       pcor=EnergyCorrections::MomentumRangeCorrectionBirch(p,vc,whichCor);
00258    }
00259    else if (ReleaseType::IsCedar(release)) {
00260       pcor=EnergyCorrections::MomentumRangeCorrectionCedar(p,vc,whichCor);
00261    }
00262    return pcor;
00263 
00264 }
00265 
00266 float EnergyCorrections::FullyCorrectEnergyFromRange(float E, //Energy from range
00267                                                      VldContext vc, //Context of this specific event
00268                                                      ReleaseType::Release_t release, //Release verion of the batch processing
00269                                                      EnergyCorrections::WhichCorrection_t whichCor)
00270 {
00271   if (ReleaseType::IsBirch(release)) {
00272     const float m=0.1057;// muon mass
00273     float p = sqrt(E*E -m*m);
00274     float pcor = EnergyCorrections::FullyCorrectMomentumFromRange(p,vc,release,whichCor);
00275     return sqrt(pcor*pcor +m*m);
00276   }
00277   else if (ReleaseType::IsCedar(release)) {
00278     return EnergyCorrections::EnergyRangeCorrectionCedar(E,vc,whichCor);
00279   }
00280   return E;
00281 }
00282 
00283 float EnergyCorrections::FullyCorrectSignedMomentumFromCurvature(float p, //Momentum from curvature
00284                                                                  VldContext vc, //Context of this specific event
00285                                                                  ReleaseType::Release_t release, //Release verion of the batch processing
00286                                                                  EnergyCorrections::WhichCorrection_t whichCor)
00287 {
00288    float pcor=p;
00289    if (ReleaseType::IsBirch(release)) {
00290       pcor=EnergyCorrections::SignedMomentumCurvatureCorrectionBirch(p,vc,whichCor);
00291    }
00292    else if (ReleaseType::IsCedar(release)) {
00293       pcor=EnergyCorrections::SignedMomentumCurvatureCorrectionCedar(p,vc,whichCor);
00294    }
00295    return pcor;
00296 
00297 }
00298 
00299 
00300 
00328 
00344 
00345 
00346 //The Calibration Group Fudge Factors
00347 namespace EnergyCorrections {
00348 
00349   static const float cgffBirchDataFD=1.018;
00350 
00351   //These Cedar_Phy numbers and CedarDaikon numbers are taken from
00352   //DocDb 3322_v1
00353   static const float cgffCedarPhyDataFD=0.9988;
00354   static const float cgffCedarPhyDataND=1.0039;
00355   static const float cgffCedarR1_24_1MCFD=(0.001737/0.001786);
00356   static const float cgffCedarR1_24_1MCND=(0.001759/0.001792);
00357 
00358   //These are the old Cedar_Phy numbers and CedarDaikon numbers that were
00359   //used in the Summer 2007 CC analysis for the summer conferences
00360   static const float cgffCedarPhyDataFDOld=0.996;
00361   static const float cgffCedarPhyDataNDOld=1.003;
00362   static const float cgffCedarR1_24_1MCFDOld=0.986;
00363   static const float cgffCedarR1_24_1MCNDOld=0.994;
00364 
00365   //These are currently just place holders for the fudge factors that may
00366   // be necessary for CedarPhyDaikon -- with the new GevPerMip
00367   static const float cgffCedarR1_24_2MCFD=cgffCedarR1_24_1MCFD*(0.001786/0.001737);
00368   static const float cgffCedarR1_24_2MCND=cgffCedarR1_24_1MCND*(0.001792/0.001759);
00369 
00370   static const float cgffCedarPhyDaikonND=1;
00371   static const float cgffCedarPhyDaikonFD=1;
00372 
00373   //Dogwood1 calibration
00374   static const float cgffDogwood1DataFD=1.0;
00375   static const float cgffDogwood1DataND=1.0;
00376   static const float cgffDogwood1DaikonFD=1.0;
00377   static const float cgffDogwood1DaikonND=1.0;
00378 }
00379 
00380 float EnergyCorrections::CalibrationGroupEnergyCorrections(float E, //Energy in MEU, GeV or SigMap
00381                                                            VldContext vc, //Context of this specific event
00382                                                            ReleaseType::Release_t release, //Release verion of the batch processing
00383                                                            EnergyCorrections::WhichCorrection_t whichCor)
00384 {
00385   //Nb: This function is called by FullyCorrectShowerEnergy, do not use it for CC Shower's
00386 
00387   float retval = E; // Default return value.
00388 
00389   MAXMSG("DataUtil",Msg::kInfo,1)
00390     << "CalibrationGroupEnergyCorrections:: Using Release Type: "
00391     << ReleaseType::AsString(release) << "\tusing correction version: "
00392     << whichCor << "\n";
00393 
00394   static Calibrator* customCalibrator = 0;
00395   if (customCalibrator ==0 ) {
00396     //Initialize. Disable warning that we're about to do something 'tricksy'.
00397     // This tricksyness is just to make a custom instance of the calibrator, so we don't
00398     // interfere with any other custom settings that the user (i.e. Jeff H) is doing
00399     // This is actually pretty safe, if an expert like me (Nathaniel) does it.
00400     MsgService::Instance()->GetStream("Calib")->SetLogLevel(Msg::kFatal);
00401     customCalibrator = Calibrator::CreateCustomCalibrator();
00402 
00403     // Turn off the units we aren't using, just to make them go faster.
00404     // "Speed holes!" -Homer Simpson
00405 
00406     customCalibrator->Set("Thermometer=SimpleCalScheme "
00407                           "PeCalibrator=SimpleCalScheme "
00408                           "LinCalibrator=SimpleCalScheme "
00409                           "StripCalibrator=SimpleCalScheme "
00410                           "AttenCalibrator=SimpleCalScheme "
00411                           "MIPCalibrator=SimpleCalScheme "
00412                           "TimeCalibrator=SimpleCalScheme ");
00413     MsgService::Instance()->GetStream("Calib")->SetLogLevel(Msg::kWarning);
00414   }
00415 
00416 
00417 
00418   // Get the reconstruction version.
00419   ReleaseType::Release_t recoVers = ReleaseType::GetRecoInfo(release);
00420 
00421   // Fudge #0:
00422   // For PRL-era data, we fudged the FD data by 1.8%
00423   if (    ReleaseType::IsBirch(release)
00424      && vc.GetSimFlag()==SimFlag::kData
00425      && vc.GetDetector()==Detector::kFar )
00426     {
00427       MAXMSG("DataUtil",Msg::kInfo,1)
00428     << "EnergyCorrections -- Applying Birch Far Detector Factor ( "
00429     << EnergyCorrections::cgffBirchDataFD << ")\n";
00430       retval = retval*EnergyCorrections::cgffBirchDataFD;
00431     }
00432 
00433 
00434 
00435   if (ReleaseType::IsCedar(release) && whichCor!=EnergyCorrections::kNoCalGroup) {
00436     //
00437     // Fudge #1
00438     // Attempt to remove the MC bug, where the drift decalibration was applied with the wrong sign.
00439     // This is a time-dependent correction which should fix the problem for cedar-daikon MC R1.24.1
00440     // This problem was fixed in R1.24.2 and R1.24.calB, but NOT R1.24.calA.
00441     //
00442     if (   ReleaseType::IsCedar(release)
00443       && ReleaseType::IsDaikon(release)
00444       && (recoVers < ReleaseType::kR1_24_2 || recoVers == ReleaseType::kR1_24_Cal )
00445       && vc.GetSimFlag()==SimFlag::kMC)
00446       {
00447     // Removes MC bug where drift correction was applied twice.
00448     // Fix it by de-applying the drift twice.
00449     MAXMSG("DataUtil",Msg::kInfo,1)
00450       << "EnergyCorrections -- Applying Infamous MC Drift Bug Correction\n";
00451 
00452     customCalibrator->Reset(vc);
00453     float drift = customCalibrator->GetDriftCorrected(1.0,PlexStripEndId());
00454     retval = retval / (drift*drift);
00455       }
00456 
00457 
00458     // Correction #2
00459     // These are the preliminary final corrections for the June 2007 cc box opening.
00460     // The numbers are taken from DocDB 3139 by Jeff Hartnell and Tingjun Yang
00461     // These are only applied if using the default (or version3) correction
00462     if (!(whichCor==EnergyCorrections::kVersion1 || whichCor==EnergyCorrections::kVersion2)) {
00463 
00464       if (vc.GetSimFlag()==SimFlag::kMC) {
00465     //For the Cedar MC we have the following possible datasets:
00466     // i) CedarDaikon -- used in Summer analysis 2007
00467     // ii) CedarPhyDaikon -- reprocessed by batch group over summer 2007
00468 
00469     if (ReleaseType::IsCedar(release) && recoVers<=ReleaseType::kR1_24_1) {
00470       //Now here we have two options either use the latest greatest numbers
00471       // or we use the old numbers from the 2007 summer analysis
00472       if (whichCor==kVersion3) {
00473         //Use the old numbers
00474         if (vc.GetDetector()==Detector::kFar) {
00475           MAXMSG("DataUtil",Msg::kInfo,1)
00476         << "EnergyCorrections -- Applying R_1_24_1 (Summer 2007) Far MC Correction Factor"
00477         << " (" << EnergyCorrections::cgffCedarR1_24_1MCFDOld << ")\n";
00478           retval*=EnergyCorrections::cgffCedarR1_24_1MCFDOld;
00479         }
00480         else if (vc.GetDetector()==Detector::kNear) {
00481           MAXMSG("DataUtil",Msg::kInfo,1)
00482         << "EnergyCorrections -- Applying R_1_24_1 (Summer 2007) Near MC Correction Factor"
00483         << " (" << EnergyCorrections::cgffCedarR1_24_1MCNDOld << ")\n";
00484           retval*=EnergyCorrections::cgffCedarR1_24_1MCNDOld;
00485         }
00486       }
00487       else {
00488         //Use the new numbers
00489         if (vc.GetDetector()==Detector::kFar) {
00490           MAXMSG("DataUtil",Msg::kInfo,1)
00491         << "EnergyCorrections -- Applying R_1_24_1 (Fall 2007) Far MC Correction Factor"
00492         << " (" << EnergyCorrections::cgffCedarR1_24_1MCFD << ")\n";
00493           retval*=EnergyCorrections::cgffCedarR1_24_1MCFD;
00494         }
00495         else if (vc.GetDetector()==Detector::kNear) {
00496           MAXMSG("DataUtil",Msg::kInfo,1)
00497         << "EnergyCorrections -- Applying R_1_24_1 (Fall 2007) Near MC Correction Factor"
00498         << " (" << EnergyCorrections::cgffCedarR1_24_1MCND << ")\n";
00499           retval*=EnergyCorrections::cgffCedarR1_24_1MCND;
00500         }
00501 
00502       }
00503     }
00504     else if (ReleaseType::IsCedar(release) && recoVers>=ReleaseType::kR1_24_2)
00505       {
00506         //Changed because we updated the GevPerMIP number in the MC
00507         // reprocessing. Bloody annoying.
00508         if (vc.GetDetector()==Detector::kFar) {
00509           MAXMSG("DataUtil",Msg::kInfo,1)
00510         << "EnergyCorrections -- Applying R_1_24_2 (Fall 2007) Far MC Correction Factor"
00511         << " (" << EnergyCorrections::cgffCedarR1_24_2MCFD << ")\n";
00512           retval*=EnergyCorrections::cgffCedarR1_24_2MCFD;
00513         }
00514         else if (vc.GetDetector()==Detector::kNear) {
00515           MAXMSG("DataUtil",Msg::kInfo,1)
00516         << "EnergyCorrections -- Applying R_1_24_2 (Fall 2007) Near MC Correction Factor"
00517         << " (" << EnergyCorrections::cgffCedarR1_24_2MCND << ")\n";
00518           retval*=EnergyCorrections::cgffCedarR1_24_2MCND;
00519         }
00520       }
00521       }
00522       else if (vc.GetSimFlag()==SimFlag::kData) {
00523     //Data corrections only available for Cedar_Phy
00524     //Once again we are going to have the option to use the old or
00525     // the new numbers
00526     if (whichCor==kVersion3) {
00527       //Use the old numbers from the Summer 2007 analysis
00528       if (recoVers>=ReleaseType::kCedarPhy) {
00529         if (vc.GetDetector()==Detector::kFar) {
00530           MAXMSG("DataUtil",Msg::kInfo,1)
00531         << "EnergyCorrections -- Applying CedarPhy (Summer 2007) Far Correction Factor"
00532         << " (" << EnergyCorrections::cgffCedarPhyDataFDOld << ")\n";
00533           retval*=EnergyCorrections::cgffCedarPhyDataFDOld;
00534         }
00535         else if (vc.GetDetector()==Detector::kNear) {
00536           MAXMSG("DataUtil",Msg::kInfo,1)
00537         << "EnergyCorrections -- Applying CedarPhy (Summer 2007) Near Correction Factor"
00538         << " (" << EnergyCorrections::cgffCedarPhyDataNDOld << ")\n";
00539           retval*=EnergyCorrections::cgffCedarPhyDataNDOld;
00540         }
00541       }
00542     }
00543     else {
00544       //Use the latest greatest numbers
00545       if (recoVers>=ReleaseType::kCedarPhy) {
00546         if (vc.GetDetector()==Detector::kFar) {
00547           MAXMSG("DataUtil",Msg::kInfo,1)
00548         << "EnergyCorrections -- Applying CedarPhy (Fall 2007) Far Correction Factor"
00549         << " (" << EnergyCorrections::cgffCedarPhyDataFD << ")\n";
00550           retval*=EnergyCorrections::cgffCedarPhyDataFD;
00551         }
00552         else if (vc.GetDetector()==Detector::kNear) {
00553           MAXMSG("DataUtil",Msg::kInfo,1)
00554         << "EnergyCorrections -- Applying CedarPhy (Fall 2007) Near Correction Factor"
00555         << " (" << EnergyCorrections::cgffCedarPhyDataND << ")\n";
00556           retval*=EnergyCorrections::cgffCedarPhyDataND;
00557         }
00558       }
00559     }
00560       }
00561     }
00562   }
00563 
00564   return retval;
00565 
00566 }
00567 
00568 
00569 
00570 // Dogwood Shower Energy Conversion
00571 // =================================
00572 //
00573 //
00574 //New function to be called directly from CandShowerHandle to set the GeV
00575 // value in the reco tree to be as close as possible to correct for the
00576 // forthcoming Dogwood release
00577 float EnergyCorrections::ShowerEnergyConversionDogwood(float E, VldContext vc)
00578 {
00579   //Two things to do:
00580   //i) apply Calibration Group tweaks
00581   //ii) apply Maskai's Reco->Truth formula
00582   float eCor=E;
00583   if (vc.GetDetector()==Detector::kFar) {
00584     //Cal group corrections
00585     if (vc.GetSimFlag()==SimFlag::kData) {
00586       eCor*=EnergyCorrections::cgffDogwood1DataFD;
00587     }
00588     else if (vc.GetSimFlag()==SimFlag::kMC) {
00589       eCor*=EnergyCorrections::cgffDogwood1DaikonFD;
00590     }
00591     //Reco-Truth Conversion
00592     eCor=EnergyCorrections::ShowerEnergyCorrectionFarDogwood(eCor,CandShowerHandle::kCC,EnergyCorrections::kDefault);
00593   }
00594   else if (vc.GetDetector()==Detector::kNear) {
00595     //Cal group corrections
00596     if (vc.GetSimFlag()==SimFlag::kData) {
00597       eCor*=EnergyCorrections::cgffDogwood1DataND;
00598     }
00599     else if (vc.GetSimFlag()==SimFlag::kMC) {
00600       eCor*=EnergyCorrections::cgffDogwood1DaikonND;
00601     }
00602     //Reco-Truth Conversion
00603     eCor=EnergyCorrections::ShowerEnergyCorrectionNearDogwood(eCor,CandShowerHandle::kCC,EnergyCorrections::kDefault);
00604   }
00605 
00606   return eCor;
00607 
00608 }
00609 
00610 
00611 
00612 //New function to be called directly from CandShowerHandle to set the GeV
00613 // value in the reco tree to be as close as possible to correct for the
00614 // forthcoming Dogwood release
00615 float EnergyCorrections::WeightedShowerEnergyConversionDogwood(float E, VldContext vc)
00616 {
00617   //Two things to do:
00618   //i) apply Calibration Group tweaks
00619   //ii) apply Maskai's Reco->Truth formula
00620   float eCor=E;
00621   if (vc.GetDetector()==Detector::kFar) {
00622     //Cal group corrections
00623     if (vc.GetSimFlag()==SimFlag::kData) {
00624       eCor*=EnergyCorrections::cgffDogwood1DataFD;
00625     }
00626     else if (vc.GetSimFlag()==SimFlag::kMC) {
00627       eCor*=EnergyCorrections::cgffDogwood1DaikonFD;
00628     }
00629     //Reco-Truth Conversion
00630     eCor=EnergyCorrections::ShowerEnergyCorrectionFarDogwood(eCor,CandShowerHandle::kWtCC,EnergyCorrections::kDefault);
00631   }
00632   else if (vc.GetDetector()==Detector::kNear) {
00633     //Cal group corrections
00634     if (vc.GetSimFlag()==SimFlag::kData) {
00635       eCor*=EnergyCorrections::cgffDogwood1DataND;
00636     }
00637     else if (vc.GetSimFlag()==SimFlag::kMC) {
00638       eCor*=EnergyCorrections::cgffDogwood1DaikonND;
00639     }
00640     //Reco-Truth Conversion
00641     eCor=EnergyCorrections::ShowerEnergyCorrectionNearDogwood(eCor,CandShowerHandle::kWtCC,EnergyCorrections::kDefault);
00642   }
00643 
00644   return eCor;
00645 
00646 }
00647 
00648 
00649 //**************** Legacy *************************************************************************************
00650 //*************************************************************************************************************
00651 //EnergyCorrections::CorrectionVersion_t EnergyCorrections::fVersion = EnergyCorrections::kUnknown;
00652 //Short_t EnergyCorrections::fSubVersion = 0;
00653 
00654 namespace EnergyCorrections {
00655   static CorrectionVersion_t fVersion = EnergyCorrections::kUnknown;
00656   static Short_t fSubVersion = 0;
00657 }
00658 
00659 void EnergyCorrections::SetCorrectionVersion(const CorrectionVersion_t& ver, 
00660                                              Short_t subver)
00661 {
00662   fVersion=ver;
00663   fSubVersion=subver;
00664 }
00665 
00666 std::string EnergyCorrections::GetCorrectionAsString() 
00667 {
00668   std::string s;
00669   switch(fVersion){
00670   case kBirch:
00671     s+="BIRCH"; break;
00672   case kCedar:
00673     s+="CEDAR"; break;
00674   case kUnknown:
00675   default:
00676     s+="???";
00677     break;
00678   }
00679   std::ostringstream os; os<<"-v"<<fSubVersion<<std::ends;
00680   s+=os.str();
00681 
00682   return s;
00683 }
00684 
00685 void EnergyCorrections::WarnUnknownVersion(const char* caller_routine)
00686 {
00687   static Short_t nwarn=0;
00688   if (nwarn<=9) {
00689     std::cerr<<"Energy Corrections: In "<<caller_routine
00690          <<"Energy Corrections: Warning, unknown correction version "
00691          <<GetCorrectionAsString()
00692          <<"Energy Corrections: Defaulting to Birch era corrections.\n"
00693          <<"Energy Corrections: Please Call SetCorrectionVersion() in the future.\n"
00694          <<std::endl;
00695     nwarn++;
00696   }
00697   if (nwarn==9) {
00698     std::cerr<<"Energy Corrections: last message of this type..."<<std::endl;
00699   }
00700 
00701 }
00702 
00703 EnergyCorrections::CorrectionVersion_t EnergyCorrections::VersionFromFilename(const char* name)
00704 {
00705   CorrectionVersion_t ver = kUnknown;
00706   std::string s=name;
00707 
00708   if (s.find("R1_18")!=std::string::npos) {
00709     ver=EnergyCorrections::kBirch;
00710   }
00711   else if (s.find("cedar")!=std::string::npos) {
00712     ver=EnergyCorrections::kCedar;
00713   }
00714   return ver;
00715 }
00716 
00717 
00718 
00719 float EnergyCorrections::CorrectMomentumFromRange(float p, bool isdata,
00720                                                   Detector::Detector_t det)
00721 {
00722   float pcor=p;
00723     switch(fVersion){
00724     case kCedar:
00725       pcor=CorrectMomentumFromRange_Cedar(p,isdata,det);
00726       break;
00727     case kBirch:
00728       pcor=CorrectMomentumFromRange_Birch(p,isdata,det);
00729       break;
00730     case kUnknown:
00731     default:
00732       WarnUnknownVersion("CorrectMomentumFromRange()");
00733       pcor=CorrectMomentumFromRange_Birch(p,isdata,det);
00734       break;
00735     }
00736     return pcor;
00737 }
00738 
00739 float EnergyCorrections::CorrectSignedMomentumFromCurvature(float p, 
00740                                                             bool isdata , 
00741                                                             Detector::Detector_t det )
00742 {
00743 
00744   float pcor=p;
00745     switch(fVersion){
00746     case kCedar:
00747       pcor=CorrectSignedMomentumFromCurvature_Cedar(p,isdata,det);
00748       break;
00749     case kBirch:
00750       pcor=CorrectSignedMomentumFromCurvature_Birch(p,isdata,det);
00751       break;
00752     case kUnknown:
00753     default:
00754       WarnUnknownVersion("CorrectSignedMomentumFromCurvature()");
00755       pcor=CorrectSignedMomentumFromCurvature_Birch(p,isdata,det);
00756       break;
00757     }
00758     return pcor;
00759 }
00760 
00761 
00762 float EnergyCorrections::CorrectEnergyFromRange(float E, bool isdata, Detector::Detector_t det)
00763 {
00764    const float m=0.1057;// mon mass
00765    float p = sqrt(E*E -m*m);
00766    float pcor = CorrectMomentumFromRange(p,isdata,det);
00767    return sqrt(pcor*pcor +m*m);
00768 }
00769 
00770 
00771 float EnergyCorrections::CorrectShowerEnergyNear(float E, const CandShowerHandle::ShowerType_t& st, int mode, bool isdata )
00772 {
00773    //People should not be using this function
00774 
00775   float ecor=E;
00776   switch(fVersion){
00777   case kCedar:
00778     ecor=CorrectShowerEnergyNear_Cedar(E,st,mode,isdata);
00779     break;
00780   case kBirch:
00781     ecor=CorrectShowerEnergyNear_Birch(E,st,mode,isdata);
00782     break;
00783   case kUnknown:
00784   default:
00785     WarnUnknownVersion("CorrectShowerEnergyNear()");
00786     ecor=CorrectShowerEnergyNear_Birch(E,st,mode,isdata);
00787     break;
00788   }
00789   return ecor;
00790 }
00791 
00792 
00793 
00794 float EnergyCorrections::CorrectShowerEnergyFar(float E, const CandShowerHandle::ShowerType_t& st, int mode, bool isdata)
00795 {
00796    //People should not be using this function
00797 
00798   float ecor=E;
00799   switch(fVersion){
00800   case kCedar:
00801     ecor=CorrectShowerEnergyFar_Cedar(E,st,mode,isdata);
00802     break;
00803   case kBirch:
00804      if (isdata) {
00805     // a correction for the FD MIP scale
00806     // for the beam data, one measured MIP
00807     // actually corresponds to 1.018 MIPs
00808     // so we must correct shower energy up
00809     const float mip_scale_correction=1.018;
00810     E*=mip_scale_correction;
00811      }
00812     ecor=CorrectShowerEnergyFar_Birch(E,st,mode,isdata);
00813     break;
00814   case kUnknown:
00815   default:
00816     WarnUnknownVersion("CorrectShowerEnergyFar()");
00817     if (isdata) {
00818        // a correction for the FD MIP scale
00819        // for the beam data, one measured MIP
00820        // actually corresponds to 1.018 MIPs
00821        // so we must correct shower energy up
00822        const float mip_scale_correction=1.018;
00823     E*=mip_scale_correction;
00824     }
00825     ecor=CorrectShowerEnergyFar_Birch(E,st,mode,isdata);
00826     break;
00827   }
00828   return ecor;
00829 
00830 }
00831 
00832 float EnergyCorrections::CorrectShowerEnergy(float E, 
00833                                              const Detector::Detector_t& det,
00834                                              const CandShowerHandle::ShowerType_t& st,
00835                                              int mode, bool isdata)
00836 {
00837    //People should not be using this function
00838   float ecor=E;
00839    if (det==Detector::kNear) {
00840       ecor = CorrectShowerEnergyNear(E,st,mode,isdata);
00841    }
00842    else if (det==Detector::kFar) {
00843       ecor = CorrectShowerEnergyFar(E,st,mode,isdata);
00844    }
00845 
00846    return ecor;
00847 }
00848 
00849 
00851 float EnergyCorrections::CorrectMomentumFromRange_Birch(float p, bool isdata, 
00852                                                         Detector::Detector_t det)
00853 {
00854   static const float c[4]={1.01334,0.05563,-0.05346,0.01205};
00855 
00856   // correction for difference in data mc steel density
00857   if (isdata){
00858     // inital correction, pre-Oxford 2006
00859     //static const float dcor=7.755/7.87;// data/mc density
00860     float dcor=1;
00861     if (det==Detector::kNear) dcor=(7.85*2.563)/(7.87*2.54);
00862     else if (det==Detector::kFar) dcor=(7.85*2.558)/(7.87*2.54);
00863 
00864     p*=dcor;
00865   }
00866   //
00867   float pcor=p/(c[0] + c[1]*log(p) + c[2]*pow(log(p), 2) + c[3]*pow(log(p),3));
00868   return pcor;
00869 }
00870 
00871 float EnergyCorrections::CorrectSignedMomentumFromCurvature_Birch(float p, bool /* isdata */, Detector::Detector_t /* det */)
00872 {
00873   // input is the signed momentum (e.g. p/q)
00874   // isdata and det are not used... but maybe in the future
00875   float pcor=p;
00876   if (pcor!=0) {
00877     // correction advertised in 1430-v2, J. Musser
00878     // note: for 1/p < 0   C=1, so correction only matters for mu+
00879     float C = (1.01+0.1*fabs(1/p))/(1.01-0.1*(1/p));
00880     pcor*=(1.0/C);
00881   }
00882   return pcor;
00883 }
00884 
00885 float EnergyCorrections::CorrectShowerEnergyNear_Birch(float E, const CandShowerHandle::ShowerType_t& st, int mode, bool /* isdata */)
00886 {
00887 
00888    //   std::cout << "CorrectShowerEnergyNear_Birch: " << E << "\t" << mode <<  std::endl;
00889    float ecor=E;
00890    if (st==CandShowerHandle::kCC){
00891       if (mode==1){
00892      // Niki Correction
00893      ecor=E/1.18;
00894       }
00895       else if (mode==2){
00896      // Andy Correction
00897      ecor=((E/1.05)*(1.-0.35*exp(-0.18*E/1.06)));
00898       }
00899    }
00900    else if (st==CandShowerHandle::kWtCC){
00901       if (mode==1){
00902      // Niki Correction
00903      ecor=((E)*(1.+0.50*exp(-1.00*E)));
00904       }
00905       else if (mode==2){
00906      // Andy Correction
00907      ecor=E/1.03;
00908       }
00909    }
00910    return ecor;
00911 }
00912 
00913 float EnergyCorrections::CorrectShowerEnergyFar_Birch(float E, const CandShowerHandle::ShowerType_t& st, int mode, bool /*isdata*/)
00914 {
00915    //   std::cout << "CorrectShowerEnergyFar_Birch: " << E << std::endl;
00916    float ecor=E;
00917    if (st==CandShowerHandle::kCC){
00918      if (mode==1){
00919        // Niki Correction
00920        ecor=((E)*(1.-0.12*exp(-0.12*E)));
00921      }
00922      else if (mode==2){
00923        // Andy Correction
00924        //     ecor=(E)*(1.-0.2*exp(-0.2*E));
00925        ecor=E*(0.99-0.035*E*exp(-0.25*E));
00926      }
00927    }
00928    else if (st==CandShowerHandle::kWtCC){
00929       if (mode==1){
00930      // Niki Correction
00931      ecor=((E)*(1.+0.18*exp(-0.35*E)));
00932       }
00933       else if (mode==2){
00934      // Andy Correction
00935      E=ecor;
00936       }
00937    }
00938    return ecor;
00939 }
00940 
00941 
00943 
00944 float EnergyCorrections::CorrectMomentumFromRange_Cedar(float p, bool /* isdata */, Detector::Detector_t /* det */)
00945 {
00946   return p;
00947 }
00948 
00949 float EnergyCorrections::CorrectSignedMomentumFromCurvature_Cedar(float p, bool /* isdata */, Detector::Detector_t /* det */)
00950 {
00951   return p;
00952 }
00953 
00954 float EnergyCorrections::CorrectShowerEnergyNear_Cedar(float E, const CandShowerHandle::ShowerType_t&  st , int /* mode */, bool /* isdata */)
00955 {
00956    float ecor=E;
00957    if (st==CandShowerHandle::kCC){
00958      ecor = ecor*(0.921+0.231*exp(-ecor*1.63));
00959    }
00960    else if (st==CandShowerHandle::kWtCC){
00961      ecor = ecor*(0.924+0.235*exp(-ecor*1.63));
00962    }
00963    return ecor;
00964 }
00965 
00966 float EnergyCorrections::CorrectShowerEnergyFar_Cedar(float E, const CandShowerHandle::ShowerType_t&  st , int /* mode */, bool /* isdata */)
00967 {
00968    float ecor=E;
00969    if (st==CandShowerHandle::kCC){
00970      ecor = ecor*(0.950+0.277*exp(-ecor*1.64));
00971    }
00972    else if (st==CandShowerHandle::kWtCC){
00973      ecor = ecor*(0.957+0.271*exp(-ecor*1.64));
00974    }
00975    return ecor;
00976 }
00977 
00979 //for Dogwood reconstruction
00980 float EnergyCorrections::ShowerEnergyCorrectionNearDogwood(float energy,
00981                                    const CandShowerHandle::ShowerType_t& st,
00982                                    EnergyCorrections::WhichCorrection_t whichCor)
00983 {
00984   switch(whichCor) {
00985   case EnergyCorrections::kVersion4:
00986     return EnergyCorrections::MasakiNearJune30_2009(energy,st);
00987   case EnergyCorrections::kDefault:
00988   default:
00989     return EnergyCorrections::MasakiNearJune30_2009(energy,st);
00990   }
00991   return energy;
00992 }
00993 
00994 float EnergyCorrections::ShowerEnergyCorrectionFarDogwood(float energy,
00995                                 const CandShowerHandle::ShowerType_t& st,
00996                                 EnergyCorrections::WhichCorrection_t whichCor)
00997 {
00998   switch(whichCor) {
00999   case EnergyCorrections::kVersion4:
01000     return EnergyCorrections::MasakiFarJune30_2009(energy,st);
01001   case EnergyCorrections::kDefault:
01002   default:
01003     return EnergyCorrections::MasakiFarJune30_2009(energy,st);
01004   }
01005   return energy;
01006 }
01007 
01008 float EnergyCorrections::ShowerEnergyCorrectionNearDogwood0(float energy,
01009                                                            const CandShowerHandle::ShowerType_t& st,
01010                                                            EnergyCorrections::WhichCorrection_t whichCor)
01011 {
01012   switch(whichCor) {
01013   case EnergyCorrections::kVersion4:
01014     return EnergyCorrections::MasakiNear_forDogwood0(energy,st);
01015   case EnergyCorrections::kDefault:
01016   default:
01017     return EnergyCorrections::MasakiNear_forDogwood0(energy,st);
01018   }
01019   return energy;
01020 }
01021 
01022 float EnergyCorrections::ShowerEnergyCorrectionFarDogwood0(float energy,
01023                                                           const CandShowerHandle::ShowerType_t& st,
01024                                                           EnergyCorrections::WhichCorrection_t whichCor)
01025 {
01026   switch(whichCor) {
01027   case EnergyCorrections::kVersion4:
01028     return EnergyCorrections::MasakiFar_forDogwood0(energy,st);
01029   case EnergyCorrections::kDefault:
01030   default:
01031     return EnergyCorrections::MasakiFar_forDogwood0(energy,st);
01032   }
01033   return energy;
01034 }
01035 
01036 
01037 //
01038 
01039 
01040 // for Cedar_phy_bhcurv reconstruction
01041 float EnergyCorrections::ShowerEnergyCorrectionNearCedarPhyBhcurve(float energy,
01042                              const CandShowerHandle::ShowerType_t& st,
01043                              EnergyCorrections::WhichCorrection_t whichCor)
01044 {
01045    switch(whichCor) {
01046    case EnergyCorrections::kVersion4:
01047       return EnergyCorrections::MasakiNearMay17thScaled(energy,st);
01048    case EnergyCorrections::kDefault:
01049    default:
01050       return EnergyCorrections::MasakiNearDec15th(energy,st);
01051    }
01052    return energy;
01053 }
01054 
01055 float EnergyCorrections::ShowerEnergyCorrectionFarCedarPhyBhcurve(float energy,
01056                              const CandShowerHandle::ShowerType_t& st,
01057                              EnergyCorrections::WhichCorrection_t whichCor)
01058 {
01059    switch(whichCor) {
01060    case EnergyCorrections::kVersion4:
01061       return EnergyCorrections::MasakiFarMay17thScaled(energy,st);
01062    case EnergyCorrections::kDefault:
01063    default:
01064       return EnergyCorrections::MasakiFarDec15th(energy,st);
01065    }
01066    return energy;
01067 }
01068 //
01069 
01070 // for cedar reconstruction
01071 float EnergyCorrections::ShowerEnergyCorrectionNearCedar(float energy,
01072                              const CandShowerHandle::ShowerType_t& st,
01073                              EnergyCorrections::WhichCorrection_t whichCor)
01074 {
01075    switch(whichCor) {
01076    case EnergyCorrections::kVersion2:
01077       return EnergyCorrections::CorrectShowerEnergyNear_Cedar(energy,st);
01078    case EnergyCorrections::kVersion1:
01079       return EnergyCorrections::MasakiNearMay17th(energy,st);
01080    case EnergyCorrections::kVersion3:
01081    case EnergyCorrections::kDefault:
01082    default:
01083       return EnergyCorrections::MasakiNearMay17thScaled(energy,st);
01084    }
01085    return energy;
01086 }
01087 
01088 float EnergyCorrections::ShowerEnergyCorrectionFarCedar(float energy,
01089                              const CandShowerHandle::ShowerType_t& st,
01090                              EnergyCorrections::WhichCorrection_t whichCor)
01091 {
01092    switch(whichCor) {
01093    case EnergyCorrections::kVersion2:
01094       return EnergyCorrections::CorrectShowerEnergyFar_Cedar(energy,st);
01095    case EnergyCorrections::kVersion1:
01096       return EnergyCorrections::MasakiFarMay17th(energy,st);
01097    case EnergyCorrections::kVersion3:
01098    case EnergyCorrections::kDefault:
01099    default:
01100       return EnergyCorrections::MasakiFarMay17thScaled(energy,st);
01101    }
01102    return energy;
01103 }
01104 //
01106 
01108 
01109 float EnergyCorrections::MasakiNearJune30_2009(float energy,
01110                                                const CandShowerHandle::ShowerType_t& st)
01111 {
01112   MAXMSG("DataUtil",Msg::kInfo,1)
01113     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector from DocDB XXXX_v4\n";
01114   float recoE=energy;
01115   float le = log10(fmin(fmax(energy,0.3),20));
01116   float we=0;
01117   if (st==CandShowerHandle::kCC){
01118     recoE = energy*(0.96922+0.175773*le -0.0684406*(2.*pow(le,2)-1)+0.00940122*(4.*pow(le,3)-3.*le));
01119   }
01120   //Warning: weight shower energy is not used after Cedar_phy_bhcurv
01121   else if (st==CandShowerHandle::kWtCC) {
01122     we = fmin(fmax(energy,0.3),20);
01123     recoE = energy*(0.96922+0.175773*le -0.0684406*(2.*pow(le,2)-1)+0.00940122*(4.*pow(le,3)-3.*le));
01124   }
01125   return recoE;
01126 }
01127 
01128 
01129 float EnergyCorrections::MasakiFarJune30_2009(float energy,
01130                            const CandShowerHandle::ShowerType_t& st)
01131 {
01132   MAXMSG("DataUtil",Msg::kInfo,1)
01133     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector from DocDB XXXX_v4\n";
01134   float recoE=energy;
01135   float le = log10(fmin(fmax(energy,0.3),20));
01136   float we=0;
01137   if (st==CandShowerHandle::kCC){
01138     recoE = energy*(1.01397 + 0.0646697*le -0.0258817*(2.*pow(le,2)-1) + 0.00117583*(4.*pow(le,3)-3.*le));
01139   }
01140   //Warning: weight shower energy is not used after Cedar_phy_bhcurv
01141   else if (st==CandShowerHandle::kWtCC) {
01142     we = fmin(fmax(energy,0.3),20);
01143     recoE= energy*(1.01397 + 0.0646697*le -0.0258817*(2.*pow(le,2)-1) + 0.00117583*(4.*pow(le,3)-3.*le));
01144   }
01145   return recoE;
01146 }
01147 
01148 // for Dogwood0 below
01149 float EnergyCorrections::MasakiNear_forDogwood0(float energy,
01150                                                const CandShowerHandle::ShowerType_t& st)
01151 {
01152   MAXMSG("DataUtil",Msg::kInfo,1)
01153     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector Dogwood0\n";
01154   float recoE=energy;
01155   float le = log10(fmin(fmax(energy,0.3),20));
01156   float we=0;
01157   if (st==CandShowerHandle::kCC){
01158     recoE = energy*(0.978739 + 0.156093*le + -0.0608388*(2.*pow(le,2)-1) + 0.00818386*(4.*pow(le,3)-3.*le));
01159   }
01160   //Warning: weight shower energy is not used after Cedar_phy_bhcurv                                                                                         
01161   else if (st==CandShowerHandle::kWtCC) {
01162     we = fmin(fmax(energy,0.3),20);
01163     recoE = energy*(0.978739 + 0.156093*le + -0.0608388*(2.*pow(le,2)-1) + 0.00818386*(4.*pow(le,3)-3.*le));
01164   }
01165   return recoE;
01166 }
01167 
01168 float EnergyCorrections::MasakiFar_forDogwood0(float energy,
01169                                               const CandShowerHandle::ShowerType_t& st)
01170 {
01171   MAXMSG("DataUtil",Msg::kInfo,1)
01172     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector Dogwood0\n";
01173   float recoE=energy;
01174   float le = log10(fmin(fmax(energy,0.3),20));
01175   float we=0;
01176   if (st==CandShowerHandle::kCC){
01177     recoE = energy*(1.02473 + 0.0429276*le + -0.016319*(2.*pow(le,2)-1) + -0.000380156*(4.*pow(le,3)-3.*le));
01178   }
01179   //Warning: weight shower energy is not used after Cedar_phy_bhcurv                                                                                         
01180   else if (st==CandShowerHandle::kWtCC) {
01181     we = fmin(fmax(energy,0.3),20);
01182     recoE= energy*(1.02473 + 0.0429276*le + -0.016319*(2.*pow(le,2)-1) + -0.000380156*(4.*pow(le,3)-3.*le));
01183   }
01184   return recoE;
01185 }
01186 //
01187 
01188 
01189 
01190 float EnergyCorrections::MasakiNearDec15th(float energy,
01191                        const CandShowerHandle::ShowerType_t& st)
01192 {
01193    //From DocDB 3077_v3
01194   MAXMSG("DataUtil",Msg::kInfo,1)
01195     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector from DocDB 3895_v4\n";
01196   float recoE=energy;
01197   float le = log10(fmin(fmax(energy,0.3),20));
01198   float we=0;
01199   if (st==CandShowerHandle::kCC){
01200     recoE = energy*(1.10973-0.248714*le +0.116769*(2.*pow(le,2)-1)-0.0200268*(4.*pow(le,3)-3.*le));
01201   }
01202   else if (st==CandShowerHandle::kWtCC) {
01203     we = fmin(fmax(energy,0.3),20);
01204     recoE= energy*(0.999461-0.00334628*we+0.0000563316*pow(we,2)+0.35232*TMath::Exp(-we*1.76594));
01205   }
01206   return recoE;
01207 }
01208 
01209 float EnergyCorrections::MasakiFarDec15th(float energy,
01210                        const CandShowerHandle::ShowerType_t& st)
01211 {
01212    //From DocDB 3077_v3
01213   MAXMSG("DataUtil",Msg::kInfo,1)
01214     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector from DocDB 3895_v4\n";
01215   float recoE=energy;
01216   float le = log10(fmin(fmax(energy,0.3),20));
01217   float we=0;
01218   if (st==CandShowerHandle::kCC){
01219     recoE = energy*( 1.15566-0.286445*le+ 0.122705*(2.*pow(le,2)-1)-0.0183855*(4.*pow(le,3)-3.*le));
01220   }
01221   else if (st==CandShowerHandle::kWtCC) {
01222     we = fmin(fmax(energy,0.3),20);
01223     recoE= energy*(0.971346+0.00314063*we-0.000135242*pow(we,2)+0.626512*TMath::Exp(-we*3.26053));
01224   }
01225   return recoE;
01226 }
01227 
01228 
01229 
01230 float EnergyCorrections::MasakiNearDec15thScaled(float energy,
01231                        const CandShowerHandle::ShowerType_t& st)
01232 {
01233    //From DocDB 3077_v3
01234   MAXMSG("DataUtil",Msg::kInfo,1)
01235     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector from DocDB 3895_v4\n";
01236   float tempE=energy/EnergyCorrections::cgffCedarPhyDaikonND;
01237   float recoE=tempE;
01238   float le = log10(fmin(fmax(tempE,0.3),20));
01239   float we=0;
01240   if (st==CandShowerHandle::kCC){
01241     recoE = tempE*(1.10973-0.248714*le +0.116769*(2.*pow(le,2)-1)-0.0200268*(4.*pow(le,3)-3.*le));
01242   }
01243   else if (st==CandShowerHandle::kWtCC) {
01244     we = fmin(fmax(energy,0.3),20);
01245     recoE= energy*(0.999461-0.00334628*we+0.0000563316*pow(we,2)+0.35232*TMath::Exp(-we*1.76594));
01246   }
01247   return recoE;
01248 }
01249 
01250 float EnergyCorrections::MasakiFarDec15thScaled(float energy,
01251                        const CandShowerHandle::ShowerType_t& st)
01252 {
01253    //From DocDB 3077_v3
01254   MAXMSG("DataUtil",Msg::kInfo,1)
01255     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector from DocDB 3895_v4\n";
01256   float tempE=energy/EnergyCorrections::cgffCedarPhyDaikonFD;
01257   float recoE=tempE;
01258   float le = log10(fmin(fmax(tempE,0.3),20));
01259   float we=0;
01260   if (st==CandShowerHandle::kCC){
01261     recoE = tempE*( 1.15566-0.286445*le+ 0.122705*(2.*pow(le,2)-1)-0.0183855*(4.*pow(le,3)-3.*le));
01262   }
01263   else if (st==CandShowerHandle::kWtCC) {
01264     we = fmin(fmax(energy,0.3),20);
01265     recoE= energy*(0.971346+0.00314063*we-0.000135242*pow(we,2)+0.626512*TMath::Exp(-we*3.26053));
01266   }
01267   return recoE;
01268 }
01269 
01270 
01271 float EnergyCorrections::MasakiNearMay17th(float energy,
01272                        const CandShowerHandle::ShowerType_t& st)
01273 {
01274    //From DocDB 3077_v3
01275   MAXMSG("DataUtil",Msg::kInfo,1)
01276     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector from DocDB 3077_v3\n";
01277   float recoE=energy;
01278    float le = log10(fmax(energy,0.2));
01279    if (st==CandShowerHandle::kCC){
01280       recoE = energy*(1.078984-0.249843*le+0.134518*(2.*pow(le,2)-1)-0.025613*(4.*pow(le,3)-3.*le));
01281    }
01282    else if (st==CandShowerHandle::kWtCC) {
01283       recoE= energy*(1.070553-0.207148*le+0.0943124*(2.*pow(le,2)-1)-0.0153231*(4.*pow(le,3)-3.*le));
01284    }
01285    return recoE;
01286 }
01287 
01288 float EnergyCorrections::MasakiFarMay17th(float energy,
01289                        const CandShowerHandle::ShowerType_t& st)
01290 {
01291    //From DocDB 3077_v3
01292   MAXMSG("DataUtil",Msg::kInfo,1)
01293     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector from DocDB 3077_v3\n";
01294    float recoE=energy;
01295    //   std::cout << "Old:\t" << recoE << std::endl;
01296    float le = log10(fmax(energy,0.2));
01297    if (st==CandShowerHandle::kCC){
01298       recoE = energy*(1.113584-0.299139*le+0.145169*(2.*pow(le,2)-1)-0.0232853*(4.*pow(le,3)-3.*le));
01299    }
01300    else if (st==CandShowerHandle::kWtCC){
01301       recoE= energy*(1.052872-0.19185*le+0.102449*(2.*pow(le,2)-1)-0.0182317*(4.*pow(le,3)-3.*le));
01302    }
01303    return recoE;
01304 }
01305 
01306 
01307 
01308 float EnergyCorrections::MasakiNearMay17thScaled(float energy,
01309                            const CandShowerHandle::ShowerType_t& st)
01310 {
01311    //From DocDB 3077_v3
01312   MAXMSG("DataUtil",Msg::kInfo,1)
01313     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Near Detector from DocDB 3077_v3 -- Scaled by Appropriate CG factor for uncalibrated data he used\n";
01314    float tempE=energy/EnergyCorrections::cgffCedarR1_24_1MCND;
01315    float recoE=tempE;
01316    float le = log10(fmax(tempE,0.2));
01317    if (st==CandShowerHandle::kCC){
01318       recoE = tempE*(1.078984-0.249843*le+0.134518*(2.*pow(le,2)-1)-0.025613*(4.*pow(le,3)-3.*le));
01319    }
01320    else if (st==CandShowerHandle::kWtCC) {
01321       recoE= tempE*(1.070553-0.207148*le+0.0943124*(2.*pow(le,2)-1)-0.0153231*(4.*pow(le,3)-3.*le));
01322    }
01323    return recoE;
01324 }
01325 
01326 
01327 float EnergyCorrections::MasakiFarMay17thScaled(float energy,
01328                         const CandShowerHandle::ShowerType_t& st)
01329 {
01330    //From DocDB 3077_v3
01331   MAXMSG("DataUtil",Msg::kInfo,1)
01332     << "EnergyCorrections -- Applying Masaki (Reco to True) Correction for Far Detector from DocDB 3077_v3 -- Scaled by Appropriate CG factor for uncalibrated data he used\n";
01333    float tempE=energy/EnergyCorrections::cgffCedarR1_24_1MCFD;
01334    float recoE=tempE;
01335    //   std::cout <<  "New:\t" <<recoE << std::endl;
01336    float le = log10(fmax(tempE,0.2));
01337    if (st==CandShowerHandle::kCC){
01338       recoE = tempE*(1.113584-0.299139*le+0.145169*(2.*pow(le,2)-1)-0.0232853*(4.*pow(le,3)-3.*le));
01339    }
01340    else if (st==CandShowerHandle::kWtCC){
01341       recoE= tempE*(1.052872-0.19185*le+0.102449*(2.*pow(le,2)-1)-0.0182317*(4.*pow(le,3)-3.*le));
01342    }
01343    return recoE;
01344 }
01346 
01348 float EnergyCorrections::MomentumRangeCorrectionBirch(float p, VldContext vc, EnergyCorrections::WhichCorrection_t /*whichCor*/)
01349 {
01350   static const float c[4]={1.01334,0.05563,-0.05346,0.01205};
01351 
01352   // correction for difference in data mc steel density
01353   if (vc.GetSimFlag()==SimFlag::kData){
01354     // inital correction, pre-Oxford 2006
01355     //static const float dcor=7.755/7.87;// data/mc density
01356     float dcor=1;
01357     if (vc.GetDetector()==Detector::kNear) dcor=(7.85*2.563)/(7.87*2.54);
01358     else if (vc.GetDetector()==Detector::kFar) dcor=(7.85*2.558)/(7.87*2.54);
01359 
01360     p*=dcor;
01361   }
01362   //
01363   float pcor=p/(c[0] + c[1]*log(p) + c[2]*pow(log(p), 2) + c[3]*pow(log(p),3));
01364   return pcor;
01365 }
01366 
01367 float EnergyCorrections::SignedMomentumCurvatureCorrectionBirch(float p, VldContext /*vc*/, WhichCorrection_t /*whichCor*/){
01368   // input is the signed momentum (e.g. p/q)
01369   // isdata and det are not used... but maybe in the future
01370   float pcor=p;
01371   if (pcor!=0) {
01372     // correction advertised in 1430-v2, J. Musser
01373     // note: for 1/p < 0   C=1, so correction only matters for mu+
01374     float C = (1.01+0.1*fabs(1/p))/(1.01-0.1*(1/p));
01375     pcor*=(1.0/C);
01376   }
01377   return pcor;
01378 }
01379 
01380 
01382 float EnergyCorrections::MomentumRangeCorrectionCedar(float p, VldContext vc, WhichCorrection_t whichCor)
01383 {
01384   //return p;
01385     const float m=0.1057;// muon mass
01386     float E = sqrt(p*p+m*m);
01387     float eCor = EnergyCorrections::EnergyRangeCorrectionCedar(E,vc,whichCor);
01388     return sqrt(eCor*eCor-m*m);
01389 }
01390 
01391 float EnergyCorrections::EnergyRangeCorrectionCedar(float E, VldContext vc, WhichCorrection_t /*whichCor*/)
01392 {
01393   MAXMSG("DataUtil",Msg::kInfo,1)
01394     << "EnergyCorrections -- Applying Energy from Range Correction for Cedar (1.018*E)-0.009 for ND Data and (1.010*E)-0.009 for everything else.\n";
01395   float eCor=E;
01396   if (vc.GetSimFlag()==SimFlag::kData && vc.GetDetector()==Detector::kNear) {
01397     eCor=(1.018*E)-0.009;
01398   }
01399   else {
01400     eCor=(1.010*E)-0.009;
01401   }
01402 
01403   return eCor;
01404 }
01405 
01406 float EnergyCorrections::SignedMomentumCurvatureCorrectionCedar(float p, VldContext /*vc*/, WhichCorrection_t /*whichCor*/)
01407 {
01408   MAXMSG("DataUtil",Msg::kInfo,1)
01409     << "EnergyCorrections -- Not applying momentum from curvature correction for Cedar\n";
01410   return p;
01411 }
01412 

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