00001 #include "SctData/FitScanResult.h"
00002 #include "SctData/FitObject.h"
00003 #include "SctDaqRootFileExt.h"
00004
00005 #include "../../AnalysisTests/AnalysisTestFramework.h"
00006 #include "../../AnalysisTests/CutUtils.h"
00007
00008 struct Info {
00009 unsigned int runNumber;
00010 unsigned int scanNumber;
00011 unsigned int index;
00012 char serial[15];
00013 };
00014 string InfoStr = "Run/i:Scan:Index:Serial/C";
00015
00016 struct FitData {
00017 double Params[5];
00018 double ChiSq;
00019
00020 FitData() {Params[0]=Params[1]=Params[2]=Params[3]=Params[4]=ChiSq=0;}
00021 };
00022 string DataStr = "P0/D:P1:P2:P3:P4:ChiSq";
00023
00024
00025
00026 FitData RodDaq;
00027 FitData SctDaq;
00028 Info info;
00029
00030
00031 string SCurveOutput = "${SCT_DAQ_ROOT}/SystemTests/logs/SCurveFit.root";
00032 string StrobeOutput = "${SCT_DAQ_ROOT}/SystemTests/logs/StrobeDelayFit.root";
00033 string TWOutput = "${SCT_DAQ_ROOT}/SystemTests/logs/TimeWalkFit.root";
00034
00035
00036 enum Mode {
00037 SCURVE,
00038 STROBE,
00039 TIMEWALK
00040 };
00041
00042
00043 class FitCompare : public AnalysisTestFramework<FitScanResult> {
00044 public:
00045 FitCompare();
00046 virtual void publishData(SctTestApiStatus* status);
00047 virtual void downloadData(string serialNumber);
00048 virtual void compare(const FitScanResult& t);
00049 virtual void setup();
00050 virtual void printAdditionalArgs();
00051 virtual int handleArg(int argc, int i, char** argv);
00052 virtual void summaryOutput();
00053 void FillTree(FitObject& ob, unsigned int index);
00054
00055 Mode mode;
00056 };
00057
00058
00059
00060 string getFileName(const TestInfo& info, unsigned int scanNumber) {
00061 ostringstream oss;
00062 oss << info.path << "/strun" << info.runNumber << "_" << scanNumber << ".root";
00063 return oss.str();
00064 }
00065
00066 double histMean(TH1& hist, unsigned int start, unsigned int nBins) {
00067 double total = 0;
00068 for (unsigned int i=start; i<start+nBins; ++i) {
00069 total += hist.GetBinContent(i);
00070 }
00071 return total/nBins;
00072 }
00073
00074 void FitCompare::compare(const FitScanResult& fit) {
00075 info.runNumber = fit.getHeader().getRunNumber();
00076 info.scanNumber = fit.getHeader().getScanNumber();
00077 strncpy(info.serial, fit.getHeader().getModuleName().c_str(), 14);
00078
00079 TestInfo testInfo;
00080 switch (mode) {
00081 case SCURVE:
00082 testInfo = moduleData.getResponseCurveInfo(fit.getHeader().getModuleName());
00083 break;
00084 case STROBE:
00085 testInfo = moduleData.getStrobeDelayInfo(fit.getHeader().getModuleName());
00086 break;
00087 case TIMEWALK:
00088 testInfo = moduleData.getTimeWalkInfo(fit.getHeader().getModuleName());
00089 break;
00090 default:
00091 cerr << "Unsupported mode" << endl;
00092 }
00093
00094 SctDaqRootFileExt file(getFileName(testInfo, fit.getHeader().getScanNumber()));
00095 unsigned int cycle = file.getCycleNum(fit.getHeader().getModuleName());
00096
00097
00098 for (unsigned int link = 0; link<nLinkModule; ++link) {
00099 if (mode == SCURVE) {
00100 auto_ptr<TH1> gMean = file.getMeanGraph(link, cycle);
00101 auto_ptr<TH1> gSigma = file.getSigmaGraph(link, cycle);
00102 auto_ptr<TH1> gChiSq = file.getChiSqGraph(link, cycle);
00103
00104 for (unsigned int i=0; i<nChannelLink; ++i) {
00105 SctDaq.Params[1] = gMean->GetBinContent(i);
00106 SctDaq.Params[2] = gSigma->GetBinContent(i);
00107 SctDaq.ChiSq = gChiSq->GetBinContent(i);
00108
00109 FitObject& fitOb = fit.getChannelFit(link, i);
00110 FillTree(fitOb, i + link*nChannelLink);
00111 }
00112 } else {
00113 for (unsigned int i=0; i<nChipLink; ++i) {
00114 FitObject& fitOb = fit.getChipFit(link, i);
00115 FillTree(fitOb, i + link*nChipLink);
00116 }
00117 }
00118 }
00119 }
00120
00121 void FitCompare::FillTree(FitObject& fitOb, unsigned int index) {
00122
00123 for (unsigned int i=0; i<fitOb.getNPar(); ++i) {
00124 RodDaq.Params[i] = fitOb.getParameter(i);
00125 }
00126 RodDaq.ChiSq = fitOb.getChiSquared() / (fitOb.getNDF() + fitOb.getNPar());
00127
00128 info.index = index;
00129 tree->Fill();
00130 }
00131
00135 void FitCompare::setup() {
00136 string name;
00137 switch (mode) {
00138 case SCURVE:
00139 name = SCurveOutput;
00140 break;
00141 case STROBE:
00142 name = StrobeOutput;
00143 break;
00144 case TIMEWALK:
00145 name = TWOutput;
00146 break;
00147 default:
00148 cerr << "Ooops, unsupported mode" << endl;
00149 }
00150 name = Env::substituteVariables(name);
00151 file = new TFile(name.c_str(), "RECREATE");
00152 tree = new TTree("FitData", "Fit Scan Comparison Data");
00153 tree->Branch("Info", &info, InfoStr.c_str());
00154 tree->Branch("SctDaq", &SctDaq, DataStr.c_str());
00155 tree->Branch("RodDaq", &RodDaq, DataStr.c_str());
00156 info.serial[14] = '\0';
00157 }
00158
00159
00160
00164 void FitCompare::downloadData(string serialNumber) {
00165 }
00166
00167 void FitCompare::publishData(SctTestApiStatus* status) {
00168 switch (mode) {
00169 case SCURVE:
00170 highLevelApi->responseCurve(status);
00171 break;
00172 case STROBE:
00173 highLevelApi->strobeDelay(status);
00174 break;
00175 case TIMEWALK:
00176 highLevelApi->timeWalk(status);
00177 break;
00178 default:
00179 cerr << "Ooops, unsupported mode" << endl;
00180 }
00181 }
00182
00186 void FitCompare::summaryOutput() {
00187 if (mode != SCURVE) return;
00188 if (cut(*tree, "mean", "(RodDaq.P1-SctDaq.P1)/SctDaq.P1*100", 0.1, 0.5, 5) > 0) {
00189 ++exitCode;
00190 cout << "Failed mean tail check" << endl;
00191 }
00192 if (cut(*tree, "sigma", "(RodDaq.P2-SctDaq.P2)/SctDaq.P2*100", 1, 2, 20) > 0) {
00193 ++exitCode;
00194 cout << "Failed sigma tail check" << endl;
00195 }
00196 if (cut(*tree, "chi", "(RodDaq.ChiSq-SctDaq.ChiSq)", 0.3, 0.5, 10) > 0) {
00197 ++exitCode;
00198 cout << "Failed ChiSq tail check" << endl;
00199 }
00200 exitCode += errorCode;
00201 }
00202
00203 FitCompare::FitCompare() : AnalysisTestFramework<FitScanResult>(".*FitScanResult", "FittedData") {
00204 mode = SCURVE;
00205 nData = 10;
00206 }
00207
00208 void FitCompare::printAdditionalArgs() {
00209 cout << "-strobe: Do strobe delay fits instead" << endl;
00210 cout << "-timewalk: Do strobe delay fits using the timewalk test instead" << endl;
00211 cout << "Default is to publish a response curve and do s-curve fitting" << endl;
00212 }
00213
00214 int FitCompare::handleArg(int argc, int i, char** argv) {
00215 if (string(argv[i]) == "-strobe") {
00216 mode = STROBE;
00217 nData = 1;
00218 } else if (string(argv[i]) == "-timewalk") {
00219 mode = TIMEWALK;
00220 nData = 10;
00221 } else {
00222 cout << "Invalid argument " << argv[i] << endl;
00223 printHelp();
00224 }
00225 return i;
00226 }
00227
00228 int main(int argc, char** argv) {
00229 TH1::AddDirectory(true);
00230 FitCompare sdc;
00231 sdc.analyzeAll(argc, argv);
00232 return sdc.getExitCode();
00233 }
00234
00235
00236
00237