TxCurrentAlgorithm.cpp

00001 #include "TxCurrentAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "SctData/TxCurrentTestResult.h"
00004 //#include "SctData/StandardDefects.h"
00005 //#include "SctData/FitObject.h"
00006 #include "SctData/RawScanResult.h"
00007 #include <cfloat>
00008 #include "TH2.h"
00009 #include "Sct/SctNames.h"
00010 
00011 // gcc296 needs a declaration of fabs
00012 #include <cmath>
00013 #include <set>
00014 
00015 using namespace std;
00016 using namespace boost;
00017 using namespace SctData;
00018 using namespace Sct;
00019 
00020 namespace SctAnalysis {
00021     
00022     bool TxCurrentAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("TxCurrentTest", auto_ptr<AnalysisAlgorithm>(new TxCurrentAlgorithm()));
00023     
00024     shared_ptr<AnalysisAlgorithm> TxCurrentAlgorithm::clone(shared_ptr<const TestData> testData, const string& moduleName) const throw() {
00025     return shared_ptr<AnalysisAlgorithm>(new TxCurrentAlgorithm(testData, moduleName, *this));
00026     }
00027 
00028     void TxCurrentAlgorithm::loadData() {
00029     loadAllRaws();
00030     }
00031 
00032     
00033     bool TxCurrentAlgorithm::canAnalyze() const{
00034     return hasAllRaws();
00035     }
00036     
00037     shared_ptr<TestResult> TxCurrentAlgorithm::createTestResult() const {
00038     return shared_ptr<TxCurrentTestResult> (new TxCurrentTestResult());
00039     }
00040        
00041   struct Wadge {
00042     TxCurrentAlgorithm::Category category;
00043     unsigned int initialThreshIndex;
00044     unsigned int width;
00045     unsigned int from() const { return initialThreshIndex; };
00046     unsigned int to() const { return initialThreshIndex+width-1; };
00047     void reset(const TxCurrentAlgorithm::Category & cat, const unsigned int index) {
00048       category = cat;
00049       initialThreshIndex = index;
00050       width=1;
00051     };
00052     bool is(const TxCurrentAlgorithm::Category & cat) const { return cat == category; }; 
00053     void increment() {
00054       ++width;
00055     };
00056     void makeEmpty() {
00057       width=0;
00058     };
00059     bool isEmpty() const {
00060       return width==0;
00061     };
00062     Wadge() {
00063       makeEmpty();
00064     };
00065     bool operator<(const Wadge & other) const {
00066       return (this->width)<(other.width);
00067     };
00068   };
00069     
00070     void TxCurrentAlgorithm::analyze() {
00071       TxCurrentTestResult & result =  *dynamic_pointer_cast<TxCurrentTestResult> ( getTestResult() );
00072       
00073       const RawScanResult& raw = *getRaw(0);
00074       result.setScanVariable(raw.getHeader().getVariable());    
00075 
00076       const SctData::ScanPoints& points=raw.getPoints();
00077       const unsigned int numberOfScanPoints = points.getNPoints();
00078  
00079       for (short unsigned int ilink=0; ilink<nLinkModule; ++ilink ) {
00080         const TH2& data = raw.getScanData(ilink);
00081         const unsigned nx = data.GetNbinsX();
00082         const unsigned ny = data.GetNbinsY();
00083         if(!(ny==numberOfScanPoints)) {
00084           throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00085         };
00086         if(ny<=0) {
00087           throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00088         };
00089         
00090         
00091        
00092         typedef unsigned int Width;
00093         typedef std::multiset<Wadge> Wadges;
00094 
00095         Wadges blackAndWhiteWadges;
00096         {
00097           Wadge currentWadge;
00098           
00099           for (unsigned int threshIndex = 0;
00100                threshIndex < ny;
00101                ++threshIndex) {
00102             const unsigned int nTriggers = points.getNEvents(threshIndex);
00103             const double txCurrent = points.getPoint(threshIndex);
00104             
00105             TxCurrentAlgorithm::Category category = undecided;
00106             bool sawZero = false;
00107             bool sawSaturation = false;
00108             for (unsigned int x=0; x<nx && category==undecided; ++x) {
00109               const Stat_t binContent_t = data.GetBinContent(x+1, threshIndex+1);
00110               const unsigned int binContent = static_cast<unsigned int>(binContent_t);
00111               if (static_cast<Stat_t>(binContent) != binContent_t) {
00112                 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);            
00113               }; 
00114               
00115               if (binContent != 0 && binContent != nTriggers) {
00116                 category = coloured;
00117                 break;
00118               };
00119               
00120               if (binContent == 0) {
00121                 sawZero = true;
00122                 continue;
00123               } else if (binContent == nTriggers) {
00124                 sawSaturation = true;
00125                 continue;
00126               };
00127             };
00128             
00129             if (category==undecided) {
00130               if (sawZero && !sawSaturation) {
00131                 category = white;
00132               } else if (sawSaturation && !sawZero) {
00133                 category = black;
00134               } else if (sawSaturation &&  sawZero) {
00135                 category = blackAndWhite;
00136               } else {
00137                 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00138               };
00139             };
00140             
00141             if (category==undecided) {
00142               throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00143             };
00144             
00145             // so now we know what this line was like!
00146             
00147             {
00148               const bool debug=false;
00149               if (debug) {
00150                 const std::string lineType = 
00151                   std::string("lineType was ") + TxCurrentAlgorithm::categoryToString(category);
00152                 
00153                 std::ostringstream os;
00154                 os << "Tx current " << txCurrent << " lineType " << lineType << " ntriggers " << nTriggers;
00155                 std::string message = os.str();
00156                 SctNames::Mrs()<< "TXCURRENTBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00157               };
00158             };
00159             
00160             if (currentWadge.isEmpty()) {
00161               currentWadge.reset(category, threshIndex);
00162             } else {
00163               // currentWadge is NOT empty !
00164               if (currentWadge.is(category)) {
00165                 currentWadge.increment();
00166               } else {
00167                 // the category just CHANGED !
00168 
00169                 // insert the wadge if it is blackAndWhite
00170                 if (currentWadge.is(blackAndWhite)) {
00171                   blackAndWhiteWadges.insert(currentWadge);
00172                 };
00173 
00174                 // reset the current wadge to match the new category
00175                 currentWadge.reset(category, threshIndex);
00176               };
00177             };
00178             
00179           };
00180           if (currentWadge.is(blackAndWhite)) {
00181             blackAndWhiteWadges.insert(currentWadge);
00182           };
00183         };
00184         // Now the blackAndWhiteWadges are fully set up!
00185         
00186         {
00187           const bool debug=true;
00188           if (debug) {
00189             for (Wadges::const_iterator it = blackAndWhiteWadges.begin();
00190                  it!=blackAndWhiteWadges.end();
00191                  ++it) {
00192               const Wadge & wadge = *it;              
00193               std::ostringstream os;
00194               os << TxCurrentAlgorithm::categoryToString(wadge.category) << " wadge of width " << wadge.width << " from " << wadge.from() << " to " << wadge.to();
00195               const std::string message = os.str();
00196               SctNames::Mrs()<< "TXCURRENTBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00197             };
00198           };
00199         };
00200 
00201         {          
00202           const bool debug=true;
00203           if (debug) {
00204             if (blackAndWhiteWadges.empty()) {
00205               SctNames::Mrs()<< "TXCURRENTBASEDONCON"<< MRS_INFORMATION<< MRS_TEXT("There were no blackAndWhite wadges for this stream!") << ENDM;
00206             } else {
00207               const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());              
00208               std::ostringstream os;
00209               os << "The largest wadge was " << TxCurrentAlgorithm::categoryToString(largestWadge.category) << " and had width " << largestWadge.width << " from " << largestWadge.from() << " to " << largestWadge.to();
00210               const std::string message = os.str();
00211               SctNames::Mrs()<< "TXCURRENTBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00212             };
00213           };
00214         };
00215 
00216         {
00217           
00218           bool pass=false;
00219           bool problem=false;
00220           
00221           // time to record the result of the test!
00222           TxCurrentTestResult::StreamResult & sr = result.getStreamResult(ilink);
00223           if (blackAndWhiteWadges.empty()) {
00224             problem=true;
00225             sr.setInvalid(); // this should be unnecessary as it already should be constructed as invalid until set otherwise ...
00226           } else {
00227             pass=true;
00228             const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00229             const unsigned int fromIndex = largestWadge.from();
00230             const unsigned int toIndex   = largestWadge.  to();
00231             const int fromThresh = static_cast<int>(points.getPoint( fromIndex ));
00232             const int   toThresh = static_cast<int>(points.getPoint(   toIndex ));
00233             const int bestThresh = (fromThresh+toThresh)/2;
00234             sr.setMinErrorFreeTxCurrent(fromThresh);
00235             sr.setMaxErrorFreeTxCurrent(  toThresh);
00236             sr.        setBestTxCurrent(bestThresh);
00237           };
00238           
00239           result.setPassed(pass);
00240           result.setProblem(problem);
00241 
00242         };
00243 
00244         //HERE LESTER
00245        
00246       };
00247       
00248      /* 
00249 
00250     float min_time[nChipModule];
00251     float max_time[nChipModule];
00252     for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00253         min_time[ichip]=FLT_MAX;  // large positive number
00254         max_time[ichip]=-FLT_MAX; // large negative number
00255     }
00256 
00257     for (unsigned index=0; index<result->getNScans() ; ++index){
00258         shared_ptr<const FitScanResult> fit=getFit(index);
00259 
00260         if (!fit.get()) {
00261         ostringstream os;
00262         os << "TxCurrentAlgorithm: unable to get scan at index " << index <<ends;
00263         throw IllegalStateError(os.str(), __FILE__, __LINE__);
00264         }
00265         
00266         if (debug) cout << "TxCurrentAlgorithm, scan #" << index << endl;
00267 
00268         for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00269         TxCurrentTestResult::ChipTWResult& cr = result->getChipResult(ichip);
00270         FitObject& fobj =fit->getChipFit(ichip);
00271         
00272         // on last point calculate calibration factor.
00273         if (debug) cout << index << "," 
00274                 << result->getNScans()-1 << endl;
00275         if (index==result->getNScans()-1){
00276             cr.calibration = // mid-rise - mid-fall
00277             fabs(fobj.getParameter(1) - fobj.getParameter(3));
00278             if (debug) {
00279             cout << "Calibration for chip "
00280                  << ichip << " = " << cr.calibration<< endl;
00281             }
00282             
00283         }
00284         if (fobj.getParameter(3) < min_time[ichip]){
00285             min_time[ichip]=fobj.getParameter(3);
00286         }
00287         if (fobj.getParameter(3) > max_time[ichip]){
00288             max_time[ichip]=fobj.getParameter(3);
00289         }
00290         }
00291     }
00292     
00293     bool pass = true;
00294 
00295     for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00296         TxCurrentTestResult::ChipTWResult& cr = result->getChipResult(ichip);
00297         cr.timewalk=max_time[ichip]-min_time[ichip];
00298         if (debug) {
00299         cout << "Time-walk for chip " << ichip
00300              << " = " <<  cr.timewalk << endl;
00301         }
00302         if (cr.timewalk<StandardDefects::TW_LO.getParameter()){
00303         result->getDefects().addDefect(Defect(StandardDefects::TW_LO, ModuleElement::Chip(ichip)));
00304         pass = false;
00305         }
00306         if (cr.timewalk>StandardDefects::TW_HI.getParameter()){
00307         result->getDefects().addDefect(Defect(StandardDefects::TW_HI, ModuleElement::Chip(ichip)));
00308         pass = false;
00309         }
00310     }
00311 
00312     result->setPassed(pass);
00313     if (debug) cout << "TxCurrentAlgorithm done" << endl;
00314       */
00315     }
00316 } // end of namespace SctAnalysis

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