00001 #include "FitAlgorithm.h"
00002 #include "../src/FitStrategy.h"
00003 #include "Fitter.h"
00004 #include <boost/scoped_ptr.hpp>
00005 #include "SctData/RawScanResult.h"
00006 #include "SctData/FitScanResult.h"
00007 #include "SctData/FitObject.h"
00008 #include "SctData/ModuleDefect.h"
00009 #include "SctData/OccupancyProjector.h"
00010 #include <TH1.h>
00011
00012 using namespace SctData;
00013 using boost::scoped_ptr;
00014
00015 namespace SctFitter {
00016
00017 FitAlgorithm::FitAlgorithm() throw() {}
00018
00019 const FitterMode& FitAlgorithm::getMode() const throw() {
00020 return mode;
00021 }
00022
00023 FitterMode& FitAlgorithm::getMode() throw() {
00024 return mode;
00025 }
00026
00027 void FitAlgorithm::setMode(const FitterMode& mode) throw() {
00028 this->mode = mode;
00029 }
00030
00031
00032 auto_ptr<FitScanResult> FitAlgorithm::doFit(const RawScanResult& raw) const throw(Sct::LogicError) {
00033 auto_ptr<FitScanResult> fitted (new FitScanResult(raw));
00034 OccupancyProjector occ(raw);
00035
00036 auto_ptr<FitObject> o (getPrototype());
00037 if (mode.fittingChannels() ) {
00038 fitted->initializeChannelFits(*o);
00039 for (unsigned int ichannel=0; ichannel<fitted->getNChannelFits() ; ++ichannel) {
00040 scoped_ptr<TH1> projection (occ.getOccupancy("name", Channel(ichannel)));
00041 FitObject& fitObject = fitted->getChannelFit(ichannel);
00042 this->doFit(*projection, fitObject, Channel(ichannel),fitted->getDefects());
00043 }
00044 }
00045 occ.vetoSevereDefects(fitted->getDefects());
00046
00047 if ( mode.fittingChips() ) {
00048 fitted->initializeChipFits(*o);
00049 for (unsigned int ichip=0; ichip<fitted->getNChipFits() ; ++ichip) {
00050 scoped_ptr<TH1> projection (occ.getOccupancy("name", Chip(ichip)));
00051 FitObject& fitObject = fitted->getChipFit(ichip);
00052 this->doFit(*projection, fitObject, Chip(ichip), fitted->getDefects());
00053 }
00054 }
00055 occ.vetoSevereDefects(fitted->getDefects());
00056 if ( mode.fittingLinks() ) {
00057 fitted->initializeLinkFits(*o);
00058 for (unsigned int ilink=0; ilink<fitted->getNLinkFits(); ++ilink) {
00059 scoped_ptr<TH1> projection (occ.getOccupancy("name", Link(ilink)));
00060 FitObject& fitObject = fitted->getLinkFit(ilink);
00061 this->doFit(*projection, fitObject, Link(ilink), fitted->getDefects());
00062 }
00063 }
00064
00065 if ( mode.doingSummary() )
00066 createSummaryHistograms(*fitted);
00067
00068 return fitted;
00069 }
00070
00071
00072 void FitAlgorithm::doFit(const TH1& hist, FitObject& fitObject,
00073 const ModuleElement& element, ModuleDefectList& defects) const throw (LogicError) {
00074 Fitter& fitter = Fitter::instance();
00075
00076
00077 checkForDefects(hist, element, defects);
00078 if ( defects.severeDefectEncompassingElement(element) ) return;
00079
00080 try {
00081 guessParameters(hist, fitObject);
00082 } catch ( MathsError& e ) {
00083 fitter.incrementFitErrors();
00084 }
00085
00086
00087 scoped_ptr<TF1> fit (fitObject.makeRootTF1());
00088
00089
00090 try {
00091 fitter.getFitStrategy().fitTH1(hist, *fit);
00092 } catch ( MathsError& e){
00093 fitter.incrementFitErrors();
00094 }
00095
00096 fitter.incrementFitsDone();
00097 fitObject = *fit;
00098 }
00099
00100
00101
00102 int FitAlgorithm::findBin(const TH1& h, const float fraction, const bool forward) throw(MathsError) {
00103 int bin=-1;
00104 float y = h.GetMaximum()*fraction;
00105 if (forward) {
00106 for(int i=1; i<=h.GetNbinsX(); i++) {
00107 if(h.GetBinContent(i)>y) {
00108 bin = i;
00109 break;
00110 }
00111 }
00112 } else {
00113 for(int i=h.GetNbinsX(); i>0; i--) {
00114 if(h.GetBinContent(i)>y) {
00115 bin = i;
00116 break;
00117 }
00118 }
00119 }
00120 if (bin==-1) {
00121 throw MathsError("FitAlgorithm::findBin no valid bin", __FILE__, __LINE__);
00122 }
00123 return bin;
00124 }
00125
00126 float FitAlgorithm::findLevel(const TH1& h, float fraction, bool forward) throw(MathsError) {
00127 int bin = FitAlgorithm::findBin(h, fraction, forward);
00128
00129
00130 float x1 = h.GetBinCenter(bin-1);
00131 float x2 = h.GetBinCenter(bin+1);
00132 float y1 = h.GetBinContent(bin-1);
00133 float y2 = h.GetBinContent(bin+1);
00134 float y = h.GetMaximum()*fraction;
00135
00136 float dy = y2-y1;
00137 if(dy==0)
00138 dy=1;
00139
00140 return x1 + ((y - y1)*(x2-x1)/(dy));
00141 }
00142
00143
00144
00145
00146 }