00001 #include "TxCurrentAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "SctData/TxCurrentTestResult.h"
00004
00005
00006 #include "SctData/RawScanResult.h"
00007 #include <cfloat>
00008 #include "TH2.h"
00009 #include "Sct/SctNames.h"
00010
00011
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
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
00164 if (currentWadge.is(category)) {
00165 currentWadge.increment();
00166 } else {
00167
00168
00169
00170 if (currentWadge.is(blackAndWhite)) {
00171 blackAndWhiteWadges.insert(currentWadge);
00172 };
00173
00174
00175 currentWadge.reset(category, threshIndex);
00176 };
00177 };
00178
00179 };
00180 if (currentWadge.is(blackAndWhite)) {
00181 blackAndWhiteWadges.insert(currentWadge);
00182 };
00183 };
00184
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
00222 TxCurrentTestResult::StreamResult & sr = result.getStreamResult(ilink);
00223 if (blackAndWhiteWadges.empty()) {
00224 problem=true;
00225 sr.setInvalid();
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
00245
00246 };
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 }
00316 }