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 bool FitAlgorithm::debug() const{
00025 return Fitter::instance().debug();
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 auto_ptr<FitObject> o (getPrototype());
00040 if (mode.fittingChannels() ) {
00041 fitted->initializeChannelFits(*o);
00042 for (unsigned int ichannel=0; ichannel<fitted->getNChannelFits() ; ++ichannel) {
00043 if (debug()) {
00044 std::cout << "Fitting channel " << ichannel << std::endl << std::endl;
00045 }
00046 std::ostringstream histname;
00047 histname << raw.getHeader().getUniqueID() << ".chan." << ichannel;
00048 scoped_ptr<TH1> projection (occ.getOccupancy(histname.str().c_str(),ModuleElement::Channel(ichannel)));
00049 FitObject& fitObject = fitted->getChannelFit(ichannel);
00050 this->doFit(*projection, fitObject, ModuleElement::Channel(ichannel),fitted->getDefects());
00051 }
00052 }
00053
00054 occ.vetoSeriousDefects(fitted->getDefects());
00055 occ.vetoMaskedChannels(raw.getConfiguration());
00056
00057 if ( mode.fittingChips() ) {
00058 fitted->initializeChipFits(*o);
00059 for (unsigned int ichip=0; ichip<fitted->getNChipFits() ; ++ichip) {
00060 if (debug()) {
00061 std::cout << "Fitting chip " << ichip << std::endl << std::endl;
00062 std::cout << "Existing defects: \n" << *fitted->getDefects().getDefectsAffectingElement(ModuleElement::Chip(ichip)) << std::endl;
00063 }
00064 std::ostringstream histname;
00065 histname << raw.getHeader().getUniqueID() << ".chip." << ichip;
00066 scoped_ptr<TH1> projection (occ.getOccupancy(histname.str().c_str(),ModuleElement::Chip(ichip)));
00067 FitObject& fitObject = fitted->getChipFit(ichip);
00068 this->doFit(*projection, fitObject, ModuleElement::Chip(ichip), fitted->getDefects());
00069 }
00070 }
00071 occ.vetoSeriousDefects(fitted->getDefects());
00072 if ( mode.fittingLinks() ) {
00073 fitted->initializeLinkFits(*o);
00074 for (unsigned int ilink=0; ilink<fitted->getNLinkFits(); ++ilink) {
00075 if (debug()) std::cout << "Fitting link " << ilink << std::endl << std::endl;
00076 std::ostringstream histname;
00077 histname << raw.getHeader().getUniqueID() << ".lk." << ilink;
00078 scoped_ptr<TH1> projection (occ.getOccupancy(histname.str().c_str(),ModuleElement::Link(ilink)));
00079 FitObject& fitObject = fitted->getLinkFit(ilink);
00080 this->doFit(*projection, fitObject, ModuleElement::Link(ilink), fitted->getDefects());
00081 }
00082 }
00083
00084 if ( mode.doingSummary() )
00085 createSummaryHistograms(*fitted);
00086
00087 return fitted;
00088 }
00089
00090
00091 void FitAlgorithm::doFit(const TH1& hist, FitObject& fitObject,
00092 const ModuleElement& element, DefectList& defects) const throw (LogicError) {
00093 Fitter& fitter = Fitter::instance();
00094
00095 if (debug()) std::cout << "Doing fit on [" << hist.GetName() << "]" << std::endl;
00096
00097
00098 checkForDefects(hist, element, defects);
00099 if ( defects.defectSeverityEncompassingElement(element) >= SERIOUS) {
00100 if (debug()) {
00101 std::cout << "Skipping because of serious defect\n" << defects << std::endl;
00102 }
00103 return;
00104 }
00105
00106 try {
00107 guessParameters(hist, fitObject);
00108 if (debug()) std::cout << "Fit object after guess parameters :\n" << fitObject << std::endl;
00109 } catch ( MathsError& e ) {
00110 fitter.incrementFitErrors();
00111 if ( debug()) std::cout << e.what();
00112 }
00113
00114
00115 scoped_ptr<TF1> fit (fitObject.makeRootTF1());
00116
00117
00118 try {
00119 fitter.internal_getFitStrategy().fitTH1(hist, *fit);
00120 } catch ( MathsError& e){
00121 fitter.incrementFitErrors();
00122 if ( debug()) std::cout << e.what();
00123 }
00124
00125 if (debug()) std::cout << "Fit object after fit :\n" << fitObject << std::endl;;
00126
00127 fitter.incrementFitsDone();
00128 fitObject = *fit;
00129 checkForDefects(fitObject, element, defects);
00130
00131 if (debug()) std::cout << defects;
00132 }
00133
00134
00135
00136 int FitAlgorithm::findBin(const TH1& h, const float fraction, const bool forward, const bool relative) throw(MathsError) {
00137 int bin=-1;
00138 float y = fraction;
00139 if (relative) y*= h.GetMaximum();
00140 if (forward) {
00141 for(int i=1; i<=h.GetNbinsX(); i++) {
00142 if(h.GetBinContent(i)>y) {
00143 bin = i;
00144 break;
00145 }
00146 }
00147 } else {
00148 for(int i=h.GetNbinsX(); i>0; i--) {
00149 if(h.GetBinContent(i)>y) {
00150 bin = i;
00151 break;
00152 }
00153 }
00154 }
00155 if (bin==-1) {
00156 throw MathsError("FitAlgorithm::findBin no valid bin", __FILE__, __LINE__);
00157 }
00158 return bin;
00159 }
00160
00161 float FitAlgorithm::findLevel(const TH1& h, float fraction, bool forward) throw(MathsError) {
00162 int bin = FitAlgorithm::findBin(h, fraction, forward);
00163
00164
00165 float x1 = h.GetBinCenter(bin-1);
00166 float x2 = h.GetBinCenter(bin+1);
00167 float y1 = h.GetBinContent(bin-1);
00168 float y2 = h.GetBinContent(bin+1);
00169 float y = h.GetMaximum()*fraction;
00170
00171 float dy = y2-y1;
00172 if(dy==0)
00173 dy=1;
00174
00175 return x1 + ((y - y1)*(x2-x1)/(dy));
00176 }
00177
00178
00179
00180
00181 }