00001 #include "CalibTracker/SiStripLorentzAngle/interface/LA_Filler_Fitter.h"
00002 #include "FWCore/Utilities/interface/EDMException.h"
00003
00004 #include <cmath>
00005 #include <boost/foreach.hpp>
00006 #include <boost/regex.hpp>
00007 #include <boost/lexical_cast.hpp>
00008 #include <boost/algorithm/string/erase.hpp>
00009 #include <TF1.h>
00010 #include <TGraphErrors.h>
00011 #include <TProfile.h>
00012
00013 LA_Filler_Fitter::Result LA_Filler_Fitter::
00014 result(Method m, const std::string name, const Book& book) {
00015 Result p;
00016 const std::string base = boost::erase_all_copy(name,method(m));
00017
00018 const TH1* const h = book[name];
00019 const TH1* const reco = book[base+"_reconstruction"];
00020 const TH1* const field = book[base+"_field"];
00021
00022 if(reco) p.reco = std::make_pair<float,float>( reco->GetMean(), reco->GetMeanError());
00023 if(field) p.field = field->GetMean();
00024 if(h) { switch(m) {
00025 case WIDTH: {
00026 const TF1*const f = h->GetFunction("LA_profile_fit"); if(!f) break;
00027 p.measured = std::make_pair<float,float>(f->GetParameter(0),f->GetParError(0));
00028 p.chi2 = f->GetChisquare();
00029 p.ndof = f->GetNDF();
00030 p.entries = (unsigned)(h->GetEntries());
00031 break;
00032 }
00033 case PROB1: case AVGV2: case AVGV3: case RMSV2: case RMSV3: {
00034 const TF1*const f = h->GetFunction("SymmetryFit"); if(!f) break;
00035 p.measured = std::make_pair<float,float>( p.reco.first + f->GetParameter(0), f->GetParameter(1) );
00036 p.chi2 = f->GetParameter(2);
00037 p.ndof = (unsigned) (f->GetParameter(3));
00038 p.entries =
00039 (m&PROB1) ? (unsigned) book[base+"_w1"]->GetEntries() :
00040 (m&(AVGV2|RMSV2)) ? (unsigned) book[base+method(AVGV2,0)]->GetEntries() :
00041 (m&(AVGV3|RMSV3)) ? (unsigned) book[base+method(AVGV3,0)]->GetEntries() : 0 ;
00042 break;
00043 }
00044 default: break;
00045 }
00046 }
00047 return p;
00048 }
00049
00050 std::map<uint32_t,LA_Filler_Fitter::Result> LA_Filler_Fitter::
00051 module_results( const Book& book, const Method m) {
00052 std::map<uint32_t,Result> results;
00053 for(Book::const_iterator it = book.begin(".*_module\\d*"+method(m)); it!=book.end(); ++it ) {
00054 const uint32_t detid = boost::lexical_cast<uint32_t>( boost::regex_replace( it->first,
00055 boost::regex(".*_module(\\d*)_.*"),
00056 std::string("\\1")));
00057 results[detid] = result(m,it->first,book);
00058 }
00059 return results;
00060 }
00061
00062 std::map<std::string,LA_Filler_Fitter::Result> LA_Filler_Fitter::
00063 layer_results( const Book& book, const Method m) {
00064 std::map<std::string,Result> results;
00065 for(Book::const_iterator it = book.begin(".*layer\\d.*"+method(m)); it!=book.end(); ++it ) {
00066 const std::string name = boost::erase_all_copy(it->first,method(m));
00067 results[name] = result(m,it->first,book);
00068 }
00069 return results;
00070 }
00071
00072 std::map<std::string, std::vector<LA_Filler_Fitter::Result> > LA_Filler_Fitter::
00073 ensemble_results( const Book& book, const Method m) {
00074 std::map<std::string, std::vector<Result> > results;
00075 for(Book::const_iterator it = book.begin(".*_sample.*"+method(m)); it!=book.end(); ++it ) {
00076 const std::string name = boost::regex_replace(it->first,boost::regex("sample\\d*_"),"");
00077 results[name].push_back(result(m,it->first,book));
00078 }
00079 return results;
00080 }
00081
00082 void LA_Filler_Fitter::
00083 summarize_ensembles(Book& book) const {
00084 typedef std::map<std::string, std::vector<Result> > results_t;
00085 results_t results;
00086 for(int m = FIRST_METHOD; m <= LAST_METHOD; m<<=1)
00087 if(methods_ & m) { results_t g = ensemble_results(book,(Method)(m)); results.insert(g.begin(),g.end());}
00088
00089 BOOST_FOREACH(const results_t::value_type group, results) {
00090 const std::string name = group.first;
00091 BOOST_FOREACH(const Result p, group.second) {
00092 const float pad = (ensembleUp_-ensembleLow_)/10;
00093 book.fill( p.reco.first, name+"_ensembleReco", 12*ensembleBins_, ensembleLow_-pad, ensembleUp_+pad );
00094 book.fill( p.measured.first, name+"_measure", 12*ensembleBins_, ensembleLow_-pad, ensembleUp_+pad );
00095 book.fill( p.measured.second, name+"_merr", 500, 0, 0.01);
00096 book.fill( (p.measured.first-p.reco.first)/p.measured.second, name+"_pull", 500, -10,10);
00097 }
00098 book[name+"_measure"]->Fit("gaus","LLQ");
00099 book[name+"_merr"]->Fit("gaus","LLQ");
00100 book[name+"_pull"]->Fit("gaus","LLQ");
00101 }
00102 }
00103
00104 std::map<std::string, std::vector<LA_Filler_Fitter::EnsembleSummary> > LA_Filler_Fitter::
00105 ensemble_summary(const Book& book) {
00106 std::map<std::string, std::vector<EnsembleSummary> > summary;
00107 for(Book::const_iterator it = book.begin(".*_ensembleReco"); it!=book.end(); ++it) {
00108 const std::string base = boost::erase_all_copy(it->first,"_ensembleReco");
00109
00110 const TH1*const reco = it->second;
00111 const TH1*const measure = book[base+"_measure"];
00112 const TH1*const merr = book[base+"_merr"];
00113 const TH1*const pull = book[base+"_pull"];
00114
00115 EnsembleSummary s;
00116 s.samples = reco->GetEntries();
00117 s.truth = reco->GetMean();
00118 s.meanMeasured = std::make_pair<float,float>( measure->GetFunction("gaus")->GetParameter(1), measure->GetFunction("gaus")->GetParError(1) );
00119 s.sigmaMeasured = std::make_pair<float,float>( measure->GetFunction("gaus")->GetParameter(2), measure->GetFunction("gaus")->GetParError(2) );
00120 s.meanUncertainty = std::make_pair<float,float>( merr->GetFunction("gaus")->GetParameter(1), merr->GetFunction("gaus")->GetParError(1) );
00121 s.pull = std::make_pair<float,float>( pull->GetFunction("gaus")->GetParameter(2), pull->GetFunction("gaus")->GetParError(2) );
00122
00123 const std::string name = boost::regex_replace(base,boost::regex("ensembleBin\\d*_"),"");
00124 summary[name].push_back(s);
00125 }
00126 return summary;
00127 }
00128
00129 std::pair<std::pair<float,float>, std::pair<float,float> > LA_Filler_Fitter::
00130 offset_slope(const std::vector<LA_Filler_Fitter::EnsembleSummary>& ensembles) {
00131 try {
00132 std::vector<float> x,y,xerr,yerr;
00133 BOOST_FOREACH(EnsembleSummary ensemble, ensembles) {
00134 x.push_back(ensemble.truth);
00135 xerr.push_back(0);
00136 y.push_back(ensemble.meanMeasured.first);
00137 yerr.push_back(ensemble.meanMeasured.second);
00138 }
00139 TGraphErrors graph(x.size(),&(x[0]),&(y[0]),&(xerr[0]),&(yerr[0]));
00140 graph.Fit("pol1");
00141 const TF1*const fit = graph.GetFunction("pol1");
00142
00143 return std::make_pair( std::make_pair(fit->GetParameter(0), fit->GetParError(0)),
00144 std::make_pair(fit->GetParameter(1), fit->GetParError(1)) );
00145 } catch(edm::Exception e) {
00146 std::cerr << "Fitting Line Failed " << std::endl << e << std::endl;
00147 return std::make_pair( std::make_pair(0,0), std::make_pair(0,0));
00148 }
00149 }
00150
00151 float LA_Filler_Fitter::
00152 pull(const std::vector<LA_Filler_Fitter::EnsembleSummary>& ensembles) {
00153 float p(0),w(0);
00154 BOOST_FOREACH(EnsembleSummary ensemble, ensembles) {
00155 const float unc2 = pow(ensemble.pull.second,2);
00156 p+= ensemble.pull.first / unc2;
00157 w+= 1/unc2;
00158 }
00159 return p/w;
00160 }
00161
00162
00163 std::ostream& operator<<(std::ostream& strm, const LA_Filler_Fitter::Result& r) {
00164 return strm << r.reco.first <<"\t"<< r.reco.second <<"\t"
00165 << r.measured.first <<"\t"<< r.measured.second <<"\t"
00166 << r.calMeasured.first <<"\t"<< r.calMeasured.second <<"\t"
00167 << r.field <<"\t"
00168 << r.chi2 <<"\t"
00169 << r.ndof <<"\t"
00170 << r.entries;
00171 }
00172
00173 std::ostream& operator<<(std::ostream& strm, const LA_Filler_Fitter::EnsembleSummary& e) {
00174 return strm << e.truth <<"\t"
00175 << e.meanMeasured.first <<"\t"<< e.meanMeasured.second <<"\t"
00176 << e.sigmaMeasured.first <<"\t"<< e.sigmaMeasured.second <<"\t"
00177 << e.meanUncertainty.first <<"\t"<< e.meanUncertainty.second << "\t"
00178 << e.pull.first <<"\t"<< e.pull.second << "\t"
00179 << e.samples;
00180 }
00181
00182
00183