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/OccupancyProjector.h"
00009 #include <TH1.h>
00010 #include <TF1.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 boost::recursive_mutex::scoped_lock lock (getMutex());
00021 return mode;
00022 }
00023
00024
00025
00026
00027
00028 void FitAlgorithm::setMode(const FitterMode& mode) throw() {
00029 boost::recursive_mutex::scoped_lock lock (getMutex());
00030 this->mode = mode;
00031 }
00032
00033
00034 auto_ptr<FitScanResult> FitAlgorithm::doFit(const RawScanResult& raw) const throw(Sct::LogicError) {
00035 boost::recursive_mutex::scoped_lock lock (getMutex());
00036 auto_ptr<FitScanResult> fitted (new FitScanResult(raw));
00037 OccupancyProjector occ(raw);
00038
00039 bool debug = (Fitter::instance().getFitStrategy().getOptions().find('Q')==string::npos && Fitter::instance().getFitStrategy().getOptions().find('q')==string::npos );
00040
00041
00042
00043
00044
00045 auto_ptr<FitObject> o (getPrototype());
00046 if (mode.fittingChannels() ) {
00047 fitted->initializeChannelFits(*o);
00048 for (unsigned int ichannel=0; ichannel<fitted->getNChannelFits() ; ++ichannel) {
00049 if (debug)
00050 cout << "Fitting channel " << ichannel << endl << endl;
00051 scoped_ptr<TH1> projection (occ.getOccupancy("name", ModuleElement::Channel(ichannel)));
00052 FitObject& fitObject = fitted->getChannelFit(ichannel);
00053 this->doFit(*projection, fitObject, ModuleElement::Channel(ichannel),fitted->getDefects());
00054 }
00055 }
00056 occ.vetoSeriousDefects(fitted->getDefects());
00057 occ.vetoMaskedChannels(raw.getConfiguration());
00058
00059 if ( mode.fittingChips() ) {
00060 fitted->initializeChipFits(*o);
00061 for (unsigned int ichip=0; ichip<fitted->getNChipFits() ; ++ichip) {
00062 if (debug)
00063 cout << "Fitting chip " << ichip << endl << endl;
00064 scoped_ptr<TH1> projection (occ.getOccupancy("name", ModuleElement::Chip(ichip)));
00065 FitObject& fitObject = fitted->getChipFit(ichip);
00066 this->doFit(*projection, fitObject, ModuleElement::Chip(ichip), fitted->getDefects());
00067 }
00068 }
00069 occ.vetoSeriousDefects(fitted->getDefects());
00070 if ( mode.fittingLinks() ) {
00071 fitted->initializeLinkFits(*o);
00072 for (unsigned int ilink=0; ilink<fitted->getNLinkFits(); ++ilink) {
00073 if (debug)
00074 cout << "Fitting link " << ilink << endl << endl;
00075 scoped_ptr<TH1> projection (occ.getOccupancy("name", ModuleElement::Link(ilink)));
00076 FitObject& fitObject = fitted->getLinkFit(ilink);
00077 this->doFit(*projection, fitObject, ModuleElement::Link(ilink), fitted->getDefects());
00078 }
00079 }
00080
00081 if ( mode.doingSummary() )
00082 createSummaryHistograms(*fitted);
00083
00084 return fitted;
00085 }
00086
00087
00088 void FitAlgorithm::doFit(const TH1& hist, FitObject& fitObject,
00089 const ModuleElement& element, DefectList& defects) const throw (LogicError) {
00090 Fitter& fitter = Fitter::instance();
00091
00092
00093 checkForDefects(hist, element, defects);
00094 if ( defects.defectSeverityEncompassingElement(element) >= SERIOUS) return;
00095
00096 try {
00097 guessParameters(hist, fitObject);
00098 } catch ( MathsError& e ) {
00099 fitter.incrementFitErrors();
00100 }
00101
00102
00103 scoped_ptr<TF1> fit (fitObject.makeRootTF1());
00104
00105
00106 try {
00107 fitter.getFitStrategy().fitTH1(hist, *fit);
00108 } catch ( MathsError& e){
00109 fitter.incrementFitErrors();
00110 }
00111
00112 fitter.incrementFitsDone();
00113 fitObject = *fit;
00114 checkForDefects(fitObject, element, defects);
00115 }
00116
00117
00118
00119 int FitAlgorithm::findBin(const TH1& h, const float fraction, const bool forward) throw(MathsError) {
00120 int bin=-1;
00121 float y = h.GetMaximum()*fraction;
00122 if (forward) {
00123 for(int i=1; i<=h.GetNbinsX(); i++) {
00124 if(h.GetBinContent(i)>y) {
00125 bin = i;
00126 break;
00127 }
00128 }
00129 } else {
00130 for(int i=h.GetNbinsX(); i>0; i--) {
00131 if(h.GetBinContent(i)>y) {
00132 bin = i;
00133 break;
00134 }
00135 }
00136 }
00137 if (bin==-1) {
00138 throw MathsError("FitAlgorithm::findBin no valid bin", __FILE__, __LINE__);
00139 }
00140 return bin;
00141 }
00142
00143 float FitAlgorithm::findLevel(const TH1& h, float fraction, bool forward) throw(MathsError) {
00144 int bin = FitAlgorithm::findBin(h, fraction, forward);
00145
00146
00147 float x1 = h.GetBinCenter(bin-1);
00148 float x2 = h.GetBinCenter(bin+1);
00149 float y1 = h.GetBinContent(bin-1);
00150 float y2 = h.GetBinContent(bin+1);
00151 float y = h.GetMaximum()*fraction;
00152
00153 float dy = y2-y1;
00154 if(dy==0)
00155 dy=1;
00156
00157 return x1 + ((y - y1)*(x2-x1)/(dy));
00158 }
00159
00160
00161
00162
00163 }