FitAlgorithm.cpp

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 //Main algorithm
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     // check the projection for defects
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     // try to guess the initial parameters of the fit
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     // make a root TF1 of the apropriate type from that FitObject
00115     scoped_ptr<TF1> fit (fitObject.makeRootTF1());
00116 
00117     // get the strategy to do the fitting
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;                     // make the fitObject equal to the TF1.
00129     checkForDefects(fitObject, element, defects);
00130 
00131     if (debug()) std::cout << defects;
00132 }
00133 
00134 //Utility methods
00135 
00136 int FitAlgorithm::findBin(const TH1& h, const float fraction, const bool forward, const bool relative) throw(MathsError) {
00137     int bin=-1;                         // to return: the bin we are interested in
00138     float y = fraction;  // the level we want to match to
00139     if (relative) y*= h.GetMaximum();
00140     if (forward) {                          // find last bin which is > y
00141         for(int i=1; i<=h.GetNbinsX(); i++) {
00142             if(h.GetBinContent(i)>y) {
00143                 bin = i;
00144                 break;
00145             }
00146         }
00147     } else {                            // find first bin which is > y
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     // We have found the bin, now linearly interpolate for value of x at fraction
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; // protection against divide by 0
00174 
00175     return x1 + ((y - y1)*(x2-x1)/(dy));
00176 }
00177 
00178 
00179 
00180 
00181 }

Generated on Mon Feb 6 14:01:20 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6