00001 #include "Sct/IS/IOManagerIS.h"
00002 #include "Sct/Exception.h"
00003 #include "Sct/LogicErrors.h"
00004 #include "Sct/SctNames.h"
00005 #include "Sct/SctParameters.h"
00006 #include "SctData/NPtGainTestResult.h"
00007 #include "SctData/ModuleDefectList.h"
00008 #include "SctData/ModuleElement.h"
00009 #include <is/isinfo.h>
00010 #include <boost/shared_ptr.hpp>
00011 #include <iostream>
00012 #include <fstream>
00013
00014 #include "Comp.h"
00015
00016 using namespace Sct;
00017 using namespace Sct::IS;
00018 using namespace boost;
00019 using namespace SctData;
00020 using namespace std;
00021
00022 string testName;
00023 string compFile;
00024 double gainTol = 1;
00025 double offsetTol = 1;
00026 double noiseTol = 34;
00027 bool debug = false;
00028 Comp cGain(gainTol);
00029 Comp cOffset(offsetTol);
00030 Comp cNoise(noiseTol);
00031 int noiseFailCount = 0;
00032 int offsetFailCount = 0;
00033 int gainFailCount = 0;
00034 int codeFailCount = 0;
00035 int nFail = 75;
00036
00037 void waitFor(string name, int nsecs) {
00038 ISInfoDictionary d(SctNames::getPartition());
00039 int tries = 0;
00040 while (!d.contains(name.c_str()) && tries < nsecs) {
00041 if (!sleep(1))
00042 ++tries;
00043 }
00044 if (tries == nsecs) {
00045 throw IllegalStateError("Didn't wait long enough", __FILE__, __LINE__);
00046 }
00047 if (debug) {
00048 cout << "Waited for " << tries << " secs" << endl;
00049 }
00050 }
00051
00052 void compareChannel(unsigned int ichannel, const ModuleDefectList& defects, const NPtGainTestResultData& data, istream& file) {
00053 unsigned int channel = 0;
00054 unsigned int code = 0;
00055 double gain = 0;
00056 double offset = 0;
00057 double noise = 0;
00058 string comment;
00059 file >> channel >> code >> gain >> offset >> noise >> comment;
00060
00061 file.ignore(256, '\n');
00062
00063 if (channel != ichannel) {
00064 ostringstream oss;
00065 oss << "Uh oh - channel read is not same as channel given. Read: " << channel << " given: " << ichannel;
00066 throw IllegalStateError(oss.str(), __FILE__, __LINE__);
00067 }
00068
00069
00070 if (code == 0) {
00071 if (defects.defectAffectingElement(Channel(channel))) {
00072 ++codeFailCount;
00073 cout << "SCTDAQ had no defects but we found some for channel " << channel << ". They are: " << endl;
00074 defects.getDefectsAffectingElement(Channel(channel))->print(cout);
00075 } else if (debug) {
00076 cout << "Both SCTDAQ and ourselves have no defects!" << endl;
00077 }
00078 } else {
00079 if (!defects.defectAffectingElement(Channel(channel))) {
00080 ++codeFailCount;
00081 cout << "We didn't find defects that SCTDAQ did for channel " << channel << ". SCTDAQ found: " << endl;
00082 cout << "Code: " << code << " " << comment << endl;
00083 } else {
00084 cout << "Both found defects for channel " << channel << ". SCTDAQ found: " << endl;
00085 cout << "Code: " << code << " " << comment << ". We found: " << endl;
00086 defects.getDefectsAffectingElement(Channel(channel))->print(cout);
00087 }
00088 }
00089
00090
00091 if (cNoise.comp(data.noise, noise)) {
00092 ++noiseFailCount;
00093 cout << "Noise different for channel " << channel << " SCTDAQ: " << noise << " Us: " << data.noise << endl;
00094 } else if (debug) {
00095 cout << "Noise same for channel " << channel << " SCTDAQ: " << noise << " Us: " << data.noise << endl;
00096 }
00097
00098 if (cGain.comp(data.gain, gain)) {
00099 ++gainFailCount;
00100 cout << "Gain different for channel " << channel << " SCTDAQ: " << gain << " Us: " << data.gain << endl;
00101 } else if (debug) {
00102 cout << "Gain same for channel " << channel << " SCTDAQ: " << gain << " Us: " << data.gain << endl;
00103 }
00104
00105 if (cOffset.comp(data.offset, offset)) {
00106 ++offsetFailCount;
00107 cout << "Offset different for channel " << channel << " SCTDAQ: " << offset << " Us: " << data.offset << endl;
00108 } else if (debug) {
00109 cout << "Offset same for channel " << channel << " SCTDAQ: " << offset << " Us: " << data.offset << endl;
00110 }
00111 }
00112
00113 bool compare(shared_ptr<NPtGainTestResult> result) {
00114
00115 ifstream file (compFile.c_str());
00116 if (!file.good()) throw IllegalStateError("Failed to open comparison file: " + compFile, __FILE__, __LINE__);
00117
00118 file.ignore(256, '\n');
00119
00120 for (unsigned int i=0; i<nChannelModule; ++i) {
00121 compareChannel(i, result->getDefects(), result->getChannelData(i), file);
00122 }
00123
00124 cout << "Summary: " << endl << "Gain av diff " << cGain.mean() << " +- " << cGain.stddev() <<endl;
00125 cout << "Noise av diff " << cNoise.mean() << " +- " << cNoise.stddev() <<endl;
00126 cout << "Offset av diff " << cOffset.mean() << " +- " << cOffset.stddev() <<endl;
00127 cout << noiseFailCount << " channels failed noise comparison" << endl;
00128 cout << gainFailCount << " channels failed gain comparison" << endl;
00129 cout << offsetFailCount << " channels failed offset comparison" << endl;
00130 cout << codeFailCount << " channels failed defect comparison" << endl;
00131
00132 return (noiseFailCount + gainFailCount + offsetFailCount + codeFailCount) < nFail;
00133 }
00134
00135 void help() {
00136 cout << "Takes 2 arguments." << endl << "The first is the name of the Test object in IS" << endl
00137 << "The second is the filename of the data to compare with (SCT DB format)" << endl
00138 << "Takes an optional 3rd argument which indicates that it is comparing 3pt gain data" << endl;
00139 exit (1);
00140 }
00141
00142 int main(int argc, char** argv) {
00143 Sct::setExceptionHandlers(argv[0]);
00144 if (argc < 3) help();
00145 testName = argv[1];
00146 compFile = argv[2];
00147 if (argc > 3) {
00148 cOffset.setTolerance(2);
00149 cNoise.setTolerance(42);
00150 }
00151
00152 try {
00153 waitFor(testName, 60);
00154 shared_ptr<Serializable> ob = IOManagerIS::instance().read(testName);
00155 shared_ptr<NPtGainTestResult> result = dynamic_pointer_cast<NPtGainTestResult>(ob);
00156 if (!result)
00157 throw IllegalStateError("Failed to read test result: " + testName, __FILE__, __LINE__);
00158 if (compare(result)) {
00159 if (debug) cout << "Success!" << endl;
00160 return 0;
00161 }
00162 else {
00163 cout << "Failed" << endl;
00164 return 1;
00165 }
00166
00167 } catch (Throwable& e) {
00168 e.sendToMrs(MRS_FATAL);
00169 return 1;
00170 }
00171 }