6 #include <TStopwatch.h>
12 #include "PixTestTiming.hh"
17 #include "constants.h"
33 PixTestTiming::PixTestTiming() :
PixTest() {}
37 std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
38 for (
unsigned int i = 0; i <
fParameters.size(); ++i) {
41 if (!parName.compare(
"fastscan")) {
44 fFastScan = atoi(sval.c_str());
45 LOG(logDEBUG) <<
"fFastScan: " << fFastScan;
48 if (!parName.compare(
"targetclk")) {
49 fTargetClk = atoi(sval.c_str());
50 LOG(logDEBUG) <<
"PixTestTiming::PixTest() targetclk = " << fTargetClk;
52 if (!parName.compare(
"ntrig")) {
53 fNTrig = atoi(sval.c_str());
54 LOG(logDEBUG) <<
"PixTestTiming::PixTest() ntrig = " << fNTrig;
62 void PixTestTiming::init()
64 LOG(logDEBUG) <<
"PixTestTiming::init()";
66 fDirectory = gFile->GetDirectory(fName.c_str());
74 fTestTip = string(Form(
"scan testboard parameter settings and check for valid readout\n")
75 +
string(
"TO BE IMPLEMENTED!!"));
76 fSummaryTip = string(
"summary plot to be implemented");
79 void PixTestTiming::bookHist(
string name)
82 LOG(logDEBUG) <<
"nothing done with " << name;
85 PixTestTiming::~PixTestTiming()
87 LOG(logDEBUG) <<
"PixTestTiming dtor";
88 std::list<TH1*>::iterator il;
92 LOG(logINFO) <<
"Write out " << (*il)->GetName();
103 bigBanner(Form(
"PixTestTiming::doTest()"));
106 TH1 *h1 = (*fDisplayedHist);
111 h1 = (*fDisplayedHist);
116 h1 = (*fDisplayedHist);
124 LOG(logINFO) <<
"PixTestTiming::doTest() done";
128 void PixTestTiming::ClkSdaScan() {
137 banner(Form(
"PixTestTiming::ClkSdaScan()"));
141 h1 =
bookTH2D(
"ClkSdaScan",
"ClkSdaScan", 20, -0.5, 19.5, 20, -0.5, 19.5);
154 map<int, vector<int> > goodclksdalist;
155 for (
int i = 0; i < 20; i++) {
156 int iclk = (i+fTargetClk) % 20;
157 vector<int> goodsdalist;
158 for (
int j = 0; j < 20; j++) {
159 int isda = (j+iclk+15) % 20;
161 LOG(logDEBUG) <<
"Checking Clk: " << iclk <<
" Sda: " << isda;
165 if (TMath::Abs(NewIA-IA) > 0.005) {
169 goodsdalist.push_back(isda);
170 if (fFastScan)
break;
175 goodclksdalist[iclk]=goodsdalist;
176 if (fFastScan && GoodClk != -1)
break;
185 for (
int i = 0; i < 20; i++) {
186 int iclk = (i+fTargetClk) % 20;
187 if (goodclksdalist.count(iclk)) {
189 vector<int> goodsdalist = goodclksdalist[iclk];
190 if (goodsdalist.size() == 1) {
191 GoodSDA=goodsdalist[0];
193 sort(goodsdalist.begin(),goodsdalist.end());
194 for (
size_t isda=1; isda<goodsdalist.size(); isda++)
if (TMath::Abs(goodsdalist[isda]-goodsdalist[isda-1])>1) goodsdalist[isda] -= 20;
195 sort(goodsdalist.begin(),goodsdalist.end());
196 GoodSDA=goodsdalist[goodsdalist.size()/2];
197 if (GoodSDA<0) GoodSDA+=20;
205 vector<pair<string,uint8_t> > GoodDelays = getDelays(GoodClk,GoodSDA);
206 LOG(logINFO) <<
"SDA delay found at clock:" << GoodClk;
207 for(vector<pair<string,uint8_t> >::iterator idelay = GoodDelays.begin(); idelay != GoodDelays.end(); ++idelay) {
208 LOG(logINFO) << idelay->first <<
": " << int(idelay->second);
209 fPixSetup->getConfigParameters()->setTbParameter(idelay->first, idelay->second);
212 }
else LOG(logERROR) <<
"No working SDA setting found!";
222 LOG(logINFO) <<
"Test took " << t <<
" ms.";
223 LOG(logINFO) <<
"PixTestTiming::ClkSdaScan() done.";
227 void PixTestTiming::PhaseScan() {
232 banner(Form(
"PixTestTiming::PhaseScan()"));
242 if (
fPixSetup->getConfigParameters()->getTbmType() ==
"tbm09") nPorts=1;
245 vector<pair<string, uint8_t> > pg_setup;
247 pg_setup.push_back(make_pair(
"resettbm", 25));
248 pg_setup.push_back(make_pair(
"trigger", 0));
251 uint16_t period = 300;
252 vector<rawEvent> daqRawEv;
258 vector <vector<int> > nROCsPort;
259 vector<TH2D*> phasehists;
260 vector<map <int, int> > TBMROCPhases;
261 for (
int itbm = 0; itbm < nTBMs; itbm++) {
264 vector<int> InitnROCPorts;
265 InitnROCPorts.assign(nPorts, 0);
266 nROCsPort.push_back(InitnROCPorts);
267 map<int, int> TBMROCPhaseMap;
268 TBMROCPhases.push_back(TBMROCPhaseMap);
269 h1 =
bookTH2D(Form(
"TBMPhaseScan%d",itbm),Form(
"TBM %d Phase Scan",itbm), 8, -0.5, 7.5, 8, -0.5, 7.5);
271 setTitles(h1,
"160MHz Phase",
"400 MHz Phase");
274 phasehists.push_back(h1);
279 for (
size_t iROC=0; iROC<rocIds.size(); iROC++) {
280 if (rocIds[iROC]<8) {
282 if (rocIds[iROC]<4) nROCsPort[0].at(0)++;
283 else nROCsPort[0].at(1)++;
286 if (rocIds[iROC]<12) nROCsPort[1].at(0)++;
287 else nROCsPort[1].at(1)++;
292 bool goodTBMPhase =
false;
293 for (
int iclk160 = 0; iclk160 < 8 && !(goodTBMPhase && fFastScan); iclk160++) {
294 for (
int iclk400 = 0; iclk400 < 8 && !(goodTBMPhase && fFastScan); iclk400++) {
295 uint8_t delaysetting = iclk160<<5 | iclk400<<2;
297 LOG(logINFO) <<
"160MHz Phase: " << iclk160 <<
" 400MHz Phase: " << iclk400 <<
" Delay Setting: " << bitset<8>(delaysetting).to_string();
301 for (
int itbm = 0; itbm < nTBMs; itbm++)
fApi->
setTbmReg(
"basea", 0, itbm);
303 vector<int> GoodROCDelays;
304 for (
int itbm = 0; itbm < nTBMs; itbm++) {
305 int MaxGoodROCSize=0;
306 bool goodROCDelay =
false;
307 for (
int delaytht = 0; delaytht < 4 && !goodROCDelay; delaytht++) {
308 if (delaytht==2)
continue;
309 h2 =
bookTH2D(Form(
"ROCPhaseScan_clk160_%d_clk400_%d_TBM_%d_delay_%d", iclk160, iclk400, itbm, delaytht),
310 Form(
"ROC Phase Scan: TBM %d Phase: %s THT Delay: %s", itbm, bitset<8>(delaysetting).to_string().c_str(), bitset<2>(delaytht).to_string().c_str()),
311 8, -0.5, 7.5, 8, -0.5, 7.5);
312 setTitles(h2,
"ROC Port 0",
"ROC Port 1");
315 h2->SetMaximum(nROCs[itbm]);
317 for (
int iport = 0; iport < nPorts; iport++) {
318 for (
int idelay = 0; idelay < 8; idelay++) {
319 int ROCDelay = (iport==0) ? (delaytht << 6) | idelay : (delaytht << 6) | (idelay << 3);
320 LOG(logDEBUG) <<
"Testing ROC Delay: " << bitset<8>(ROCDelay).to_string() <<
" For TBM Core: " << itbm;
324 LOG(logDEBUG) <<
"Events in Data Buffer: " << daqRawEv.size();
325 if (
int(daqRawEv.size()) < fNTrig)
continue;
326 for (
int ievent = 0; ievent<fNTrig; ievent++) {
327 rawEvent event = daqRawEv.at(ievent);
328 LOG(logDEBUG) <<
"Event: " << event;
329 vector<int> tbmheaders;
330 vector<int> tbmtrailers;
332 for (
int idata = 0; idata < int(event.data.size()); idata++) {
333 if (event.data.at(idata) >> 8 == 160) tbmheaders.push_back(idata);
334 if (event.data.at(idata) >> 8 == 192) tbmtrailers.push_back(idata);
335 if (header==0 &&
int(tbmheaders.size())==itbm+1 &&
int(tbmtrailers.size())==itbm && event.data.at(idata) >> 12 == 4) header = event.data.at(idata);
337 if (
int(tbmheaders.size()) != nTBMs ||
int(tbmtrailers.size()) != nTBMs || header==0)
continue;
338 int rocheader_count = 0;
339 int StartData = tbmheaders[itbm]+2;
340 int StopData = tbmtrailers[itbm]-2;
341 for (
int jport=0; jport<nPorts; jport++) {
342 if (jport < iport) StartData += nROCsPort[itbm][jport];
343 if (jport > iport) StopData -= nROCsPort[itbm][jport];
345 for (
int idata = StartData; idata <= StopData; idata++)
if (event.data.at(idata) >> 2 == header >> 2) rocheader_count++;
346 LOG(logDEBUG) << rocheader_count <<
" ROC headers (" << hex << (header) << dec <<
") found for TBM Core " << itbm <<
" for Port " << iport <<
". Looking for " << nROCsPort[itbm][iport] <<
".";
347 for (
int ibin=0; ibin<8; ibin++) {
348 if (iport==0) h2->Fill(idelay, ibin, rocheader_count);
349 if (iport==1) h2->Fill(ibin, idelay, rocheader_count);
354 pair <int, int> GoodRegion = getGoodRegion(h2, nROCs[itbm]*fNTrig);
355 LOG(logDEBUG) << h2->GetTitle() <<
" - Size: " << GoodRegion.first <<
" Delay: " << GoodRegion.second;
356 h2->Scale(1/
float(fNTrig));
357 if (GoodRegion.first > MaxGoodROCSize) {
358 MaxGoodROCSize = GoodRegion.first;
359 int ROCDelay = (delaytht << 6) | GoodRegion.second;
360 if (
int(GoodROCDelays.size()) < itbm+1) GoodROCDelays.push_back(ROCDelay);
361 else GoodROCDelays[itbm] = ROCDelay;
362 if (fFastScan && GoodRegion.first > 0) {
364 fPixSetup->getConfigParameters()->setTbmDac(
"basea", ROCDelay, itbm);
368 if (GoodRegion.first) {
376 phasehists[itbm]->Fill(iclk160, iclk400, MaxGoodROCSize);
377 if (
int(GoodROCDelays.size())==itbm+1) {
378 TBMROCPhases[itbm][delaysetting] = GoodROCDelays[itbm];
380 fPixSetup->getConfigParameters()->setTbmDac(
"basea", GoodROCDelays[itbm], itbm);
384 if (
int(GoodROCDelays.size())==nTBMs){
386 if (fFastScan)
fPixSetup->getConfigParameters()->setTbmDac(
"basee", delaysetting, 0);
387 LOG(logINFO) <<
"Good timings found for TBMPhase basee: " << bitset<8>(delaysetting).to_string();
388 for (
int itbm = 0; itbm < nTBMs; itbm++) LOG(logINFO) <<
"ROCPhase TBM Core " << itbm <<
" basea: " << bitset<8>(GoodROCDelays[itbm]).to_string();
393 banner(Form(
"PixTestTiming::Phase Scan Completed"));
397 pair<int, int> BestBin(0,0);
398 for (
int xbin=1; xbin<=phasehists[0]->GetNbinsX(); xbin++) {
399 for (
int ybin=1; ybin<=phasehists[0]->GetNbinsY(); ybin++) {
401 for (
int itbm=0; itbm<nTBMs; itbm++) BinSum += phasehists[itbm]->GetBinContent(xbin,ybin);
402 if (BinSum > MaxBinSum) {
404 BestBin = make_pair(xbin-1, ybin-1);
408 int delaysetting = BestBin.first<<5 | BestBin.second<<2;
410 fPixSetup->getConfigParameters()->setTbmDac(
"basee", delaysetting, 0);
411 LOG(logINFO) <<
"Final timing for TBMPhase basee: " << bitset<8>(delaysetting).to_string();
412 for (
int itbm = 0; itbm < nTBMs; itbm++) {
413 fApi->
setTbmReg(
"basea", TBMROCPhases[itbm][delaysetting], itbm);
414 fPixSetup->getConfigParameters()->setTbmDac(
"basea", TBMROCPhases[itbm][delaysetting], itbm);
415 LOG(logINFO) <<
"ROCPhase TBM Core " << itbm <<
" basea: " << bitset<8>(TBMROCPhases[itbm][delaysetting]).to_string();
423 LOG(logERROR) <<
"No working TBM-ROC Phase found. Verify you have disabled bypassed ROCs in pXar on the h/w tab.";
424 for (
int itbm = 0; itbm < nTBMs; itbm++) LOG(logERROR) <<
"PhaseScan searched for " << nROCs[itbm] <<
" ROCs on TBM Core " << itbm <<
".";
428 for (
int itbm = 0; itbm < nTBMs && !fFastScan; itbm++) {
429 phasehists[itbm]->Draw(
getHistOption(phasehists[itbm]).c_str());
436 LOG(logINFO) <<
"Test took " << t <<
" ms.";
437 LOG(logINFO) <<
"PixTestTiming::PhaseScan() done.";
441 void PixTestTiming::TimingTest() {
446 banner(Form(
"PixTestTiming::TimingTest()"));
452 vector<pair<string, uint8_t> > pg_setup;
453 pg_setup.push_back(make_pair(
"resetroc", 25));
454 pg_setup.push_back(make_pair(
"trigger", 0));
457 uint16_t period = 300;
458 vector<rawEvent> daqRawEv;
465 LOG(logINFO) << daqRawEv.size() <<
" events found. " << fNTrig <<
" events expected.";
467 for (
size_t ievent=0; ievent<daqRawEv.size(); ievent++) {
468 banner(Form(
"Decoding Event Number %d",
int(ievent)),logDEBUG);
469 rawEvent event = daqRawEv.at(ievent);
470 LOG(logDEBUG) <<
"Event: " << event;
471 vector<int> tbmheaders;
472 vector<int> tbmtrailers;
473 vector<int> rocheaders;
474 for (
int idata=0; idata < int(event.data.size()); idata++) {
475 if (event.data.at(idata) >> 8 == 160) tbmheaders.push_back(idata);
476 if (event.data.at(idata) >> 8 == 192) tbmtrailers.push_back(idata);
477 if (event.data.at(idata) >> 12 == 4) rocheaders.push_back(idata);
479 LOG(logDEBUG) << tbmheaders.size() <<
" TBM Headers found. " << nTBMs <<
" TBM Headers expected.";
480 LOG(logDEBUG) << tbmtrailers.size() <<
" TBM Trailers found. " << nTBMs <<
" TBM Trailers expected.";
481 LOG(logDEBUG) << rocheaders.size() <<
" ROC Headers found. " << nROCs <<
" ROC Headers expected." << endl;
482 if (tbmheaders.size()==nTBMs && tbmtrailers.size()==nTBMs && rocheaders.size()==nROCs) ngoodevents++;
485 LOG(logINFO) << Form(
"The fraction of properly decoded events is %4.2f%%: ",
float(ngoodevents)/fNTrig*100) << ngoodevents <<
"/" << fNTrig;
486 LOG(logINFO) <<
"Test took " << t <<
" ms.";
487 LOG(logINFO) <<
"PixTestTiming::TimingTest() done.";
492 void PixTestTiming::LevelScan() {
499 banner(Form(
"PixTestTiming::LevelScan()"));
503 uint16_t period = 300;
507 h1 =
bookTH1D(
"LevelScan",
"Level Scan", 16, -0.5, 15.5);
509 setTitles(h1,
"DTB Level",
"Good Events");
516 vector<pair<string, uint8_t> > pg_setup;
517 pg_setup.push_back(make_pair(
"resetroc", 25));
518 pg_setup.push_back(make_pair(
"trigger", 0));
522 vector<pair<string, uint8_t> > InitTBMParameters =
fPixSetup->getConfigParameters()->getTbParameters();
524 vector<uint8_t> GoodLevels;
525 vector<rawEvent> daqRawEv;
527 for (uint8_t ilevel=15; ilevel>3; ilevel--){
528 LOG(logDEBUG) <<
"Testing Level: " << int(ilevel);
529 fPixSetup->getConfigParameters()->setTbParameter(
"level", ilevel);
538 for (
size_t ievent=0; ievent<daqRawEv.size(); ievent++) {
539 rawEvent event = daqRawEv.at(ievent);
540 LOG(logDEBUG) <<
"Event: " << event;
541 vector<int> tbmheaders;
542 vector<int> tbmtrailers;
543 vector<int> rocheaders;
544 for (
int idata=0; idata < int(event.data.size()); idata++) {
545 if (event.data.at(idata) >> 8 == 160) tbmheaders.push_back(idata);
546 if (event.data.at(idata) >> 8 == 192) tbmtrailers.push_back(idata);
547 if (event.data.at(idata) >> 12 == 4) rocheaders.push_back(idata);
549 if (tbmheaders.size()==nTBMs && tbmtrailers.size()==nTBMs && rocheaders.size()==nROCs) ngoodevents++;
551 if (ngoodevents) h1->Fill(
int(ilevel), ngoodevents);
552 if (ngoodevents==fNTrig) GoodLevels.push_back(ilevel);
555 if (GoodLevels.size()) {
556 uint8_t MeanLevel = 0;
557 if (GoodLevels.size()==1) MeanLevel = GoodLevels.front();
558 else MeanLevel = GoodLevels[GoodLevels.size()/2];
559 fPixSetup->getConfigParameters()->setTbParameter(
"level", MeanLevel);
561 LOG(logINFO) <<
"DTB Level set to " << int(MeanLevel);
563 LOG(logERROR) <<
"No working level found! Verify you have disabled bypassed ROCs in pXar on the h/w tab.";
564 LOG(logERROR) <<
"Level scan searched for " << nROCs <<
" total ROCs and " << nTBMs <<
" TBM Headers and Trailers.";
575 LOG(logINFO) <<
"Test took " << t <<
" ms.";
576 LOG(logINFO) <<
"PixTestTiming::LevelScan() done.";
581 vector<pair<string,uint8_t> > PixTestTiming::getDelays(uint8_t clk, uint8_t sda) {
582 vector<pair<string,uint8_t> > sigdelays;
583 sigdelays.push_back(make_pair(
"clk", clk%20));
584 sigdelays.push_back(make_pair(
"ctr", clk%20));
585 sigdelays.push_back(make_pair(
"sda", sda%20));
586 sigdelays.push_back(make_pair(
"tin", (clk+5)%20));
591 pair <int, int> PixTestTiming::getGoodRegion(TH2D* hist,
int hits) {
593 if (hist->GetEntries()==0)
return make_pair(0,0);
595 int MaxGoodRegionSize=0;
597 for (
int startbinx=1; startbinx<=hist->GetNbinsX(); startbinx++) {
598 for (
int startbiny=1; startbiny<=hist->GetNbinsY(); startbiny++) {
599 if (
int(hist->GetBinContent(startbinx,startbiny))!=hits)
continue;
600 for (
int regionsize=0; regionsize<8; regionsize++) {
601 bool regiongood =
true;
602 for (
int xoffset=0; xoffset<=regionsize && regiongood; xoffset++) {
603 for (
int yoffset=0; yoffset<=regionsize && regiongood; yoffset++) {
604 int checkbinx = (startbinx+xoffset>8) ? startbinx+xoffset-8 : startbinx+xoffset;
605 int checkbiny = (startbiny+yoffset>8) ? startbiny+yoffset-8 : startbiny+yoffset;
606 if (
int(hist->GetBinContent(checkbinx,checkbiny))!=hits) regiongood=
false;
609 if (regiongood && regionsize+1>MaxGoodRegionSize) {
610 MaxGoodRegionSize=regionsize+1;
611 GoodROCDelay = (startbinx-1+regionsize/2)%8 | (startbiny-1+regionsize/2)%8<<3;
617 return make_pair(MaxGoodRegionSize, GoodROCDelay);
622 void PixTestTiming::saveParameters() {
623 LOG(logINFO) <<
"PixTestTiming:: Write Tbm parameters to file.";
624 fPixSetup->getConfigParameters()->writeTbParameterFile();
632 transform(command.begin(), command.end(), command.begin(), ::tolower);
633 LOG(logDEBUG) <<
"running command: " << command;
634 if (!command.compare(
"clocksdascan")) {
638 if (!command.compare(
"phasescan")) {
642 if (!command.compare(
"saveparameters")) {
646 if (!command.compare(
"timingtest")) {
650 if (!command.compare(
"levelscan")) {
654 LOG(logDEBUG) <<
"did not find command ->" << command <<
"<-";
static void replaceAll(std::string &str, const std::string &from, const std::string &to)
in str, replace all occurences of from to to
void runCommand(std::string)
allow execution of any button in the test
void setPatternGenerator(std::vector< std::pair< std::string, uint8_t > > pg_setup)
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
PixSetup * fPixSetup
all necessary stuff in one place
std::vector< uint8_t > getEnabledRocI2Caddr()
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
void setTestboardDelays(std::vector< std::pair< std::string, uint8_t > > sig_delays)
TDirectory * fDirectory
where the root histograms will end up
void restoreDacs(bool verbose=false)
restore all DACs
std::list< TH1 * >::iterator fDisplayedHist
pointer to the histogram currently displayed
TH1D * bookTH1D(std::string sname, std::string title, int nbins, double xmin, double xmax)
book a TH1D, adding version information to the name and title
virtual std::string getHistOption(TH1 *)
get the hist display options (if stored in fHistOptions)
void cacheDacs(bool verbose=false)
cache all DACs
bool setTbmReg(std::string regName, uint8_t regValue, uint8_t tbmid)
std::list< TH1 * > fHistList
list of histograms available in PixTab::next and PixTab::previous
void setTitles(TH1 *h, const char *sx, const char *sy, float size=0.05, float xoff=1.1, float yoff=1.1, float lsize=0.05, int font=42)
utility to set histogram titles
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
TH2D * bookTH2D(std::string sname, std::string title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double max)
book a TH2D, adding version information to the name and title
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
void update()
signal to PixTab to update the canvas
pxar::pxarCore * fApi
pointer to the API
uint16_t daqTrigger(uint32_t nTrig=1, uint16_t period=0)
void init()
sets all test parameters
void doTest()
function connected to "DoTest" button of PixTab
std::vector< std::pair< std::string, uint8_t > > getTbmDACs(size_t tbmId)
std::vector< rawEvent > daqGetRawEventBuffer()