void YarrGui::doScan(QString qn){ std::ofstream *tmpOfCout = new std::ofstream("deleteMeCout.txt"); std::streambuf *coutBuf = std::cout.rdbuf(tmpOfCout->rdbuf()); std::ofstream *tmpOfCerr = new std::ofstream("deleteMeCerr.txt"); std::streambuf *cerrBuf = std::cerr.rdbuf(tmpOfCerr->rdbuf()); int N = ui->feTree->topLevelItemCount(); int M = scanVec.size(); for(int j = 0; j < N; j++){ scanDone = false; processorDone = false; if(!(ui->feTree->topLevelItem(j)->child(4)->checkState(1))){continue;} //Is the Scan checkbox checked? Fei4 * fe = dynamic_cast<Fei4*>(bk->feList.at(j)); ScanBase * s = nullptr; if(qn == "NS") {s = new Fei4NoiseScan(bk);} if(qn == "DS") {s = new Fei4DigitalScan(bk);} if(qn == "AS") {s = new Fei4AnalogScan(bk);} if(qn == "TS") {s = new Fei4ThresholdScan(bk);} if(qn == "ToTS") {s = new Fei4TotScan(bk);} if(qn == "GTT") {s = new Fei4GlobalThresholdTune(bk);} if(qn == "GPT") {s = new Fei4GlobalPreampTune(bk);} if(qn == "PTT") {s = new Fei4PixelThresholdTune(bk);} if(qn == "PPT") {s = new Fei4PixelPreampTune(bk);} if(qn == "CS") {s = &cs;} if(s == nullptr){ std::cerr << "Invalid scan QString parameter passed or scan object construction failed. Returning...\n"; return; } QTreeWidgetItem * plotTreeItem = nullptr; //Plot tree item for current FE for(int k = 0; k < ui->plotTree->topLevelItemCount(); k++){ //Is the current FE already in the tree? ... if(ui->plotTree->topLevelItem(k)->text(0) == ui->feTree->topLevelItem(j)->text(0)){ plotTreeItem = ui->plotTree->topLevelItem(k); break; } } if(plotTreeItem == nullptr){ //... if not: create a branch for it plotTreeItem = new QTreeWidgetItem(ui->plotTree); plotTreeItem->setText(0, ui->feTree->topLevelItem(j)->text(0)); } QTreeWidgetItem * plotTreeItemDS = new QTreeWidgetItem(); //plot tree item for current scan plotTreeItemDS->setText(0, qn); plotTreeItem->addChild(plotTreeItemDS); fe->histogrammer = new Fei4Histogrammer(); fe->histogrammer->connect(fe->clipDataFei4, fe->clipHisto); fe->ana = new Fei4Analysis(bk, fe->getRxChannel()); fe->ana->connect(s, fe->clipHisto, fe->clipResult); if (qn=="CS"){ CustomScan * tmp; tmp = dynamic_cast<CustomScan*>(s); if(tmp->bA.at(OCC_MAP) == true) {fe->histogrammer->addHistogrammer(new OccupancyMap());} if(tmp->bA.at(TOT_MAP) == true) {fe->histogrammer->addHistogrammer(new TotMap());} if(tmp->bA.at(TOT_2_MAP) == true) {fe->histogrammer->addHistogrammer(new Tot2Map());} if(tmp->bA.at(OCC_ANA) == true) {fe->ana->addAlgorithm(new OccupancyAnalysis());} if(tmp->bA.at(NOISE_ANA) == true) {fe->ana->addAlgorithm(new NoiseAnalysis());} if(tmp->bA.at(TOT_ANA) == true) {fe->ana->addAlgorithm(new TotAnalysis());} if(tmp->bA.at(S_CU_FIT) == true) {fe->ana->addAlgorithm(new ScurveFitter());} if(tmp->bA.at(PIX_THR) == true) {fe->ana->addAlgorithm(new OccPixelThresholdTune);} }else{ fe->histogrammer->addHistogrammer(new OccupancyMap()); if (qn == "ToTS" || qn == "GPT" || qn == "PPT"){ fe->histogrammer->addHistogrammer(new TotMap()); fe->histogrammer->addHistogrammer(new Tot2Map()); } if(qn == "NS") {fe->ana->addAlgorithm(new NoiseAnalysis());} if(qn == "DS") {fe->ana->addAlgorithm(new OccupancyAnalysis());} if(qn == "AS") {fe->ana->addAlgorithm(new OccupancyAnalysis());} if(qn == "TS") {fe->ana->addAlgorithm(new ScurveFitter());} if(qn == "ToTS") {fe->ana->addAlgorithm(new TotAnalysis());} if(qn == "GTT") {fe->ana->addAlgorithm(new OccGlobalThresholdTune());} if(qn == "GPT") {fe->ana->addAlgorithm(new TotAnalysis());} if(qn == "PTT") {fe->ana->addAlgorithm(new OccPixelThresholdTune());} if(qn == "PPT") {fe->ana->addAlgorithm(new TotAnalysis());} } s->init(); ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //1 s->preScan(); ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //2 unsigned int numThreads = std::thread::hardware_concurrency(); //std::cout << "-> Starting " << numThreads << " processor Threads:" << std::endl; std::vector<std::thread> procThreads; for (unsigned i=0; i<numThreads; i++){ procThreads.push_back(std::thread(process, bk, &scanDone)); //std::cout << " -> Processor thread #" << i << " started!" << std::endl; } std::vector<std::thread> anaThreads; //std::cout << "-> Starting histogrammer and analysis threads:" << std::endl; if (fe->isActive()){ anaThreads.push_back(std::thread(analysis, fe->histogrammer, fe->ana, &processorDone)); //std::cout << " -> Analysis thread of Fe " << fe->getRxChannel() << std::endl; } s->run(); ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //3 s->postScan(); ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //4 scanDone = true; for (unsigned i=0; i<numThreads; i++){ procThreads[i].join(); } ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //5 processorDone = true; for(unsigned i=0; i<anaThreads.size(); i++){ anaThreads[i].join(); } ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //6 if(qn != "CS") { delete s; } // fe->toFileBinary(); // fe->ana->plot("Scan_GUI"); //DEBUG begin [plotting] //clear raw data while(fe->clipDataFei4->size() != 0){ fe->clipDataFei4->popData(); } //clear raw data while(fe->clipHisto->size() != 0){ fe->clipHisto->popData(); } while(fe->clipResult->size() != 0){ HistogramBase * showMe = fe->clipResult->popData(); //Add tab to plot tab widget QCustomPlot * tabScanPlot = new QCustomPlot(ui->scanPlots_tabWidget); // X QWidget * addToTabWidget = dynamic_cast<QWidget*>(tabScanPlot); QString newTabName = qn + ' ' + ui->feTree->topLevelItem(j)->text(0); ui->scanPlots_tabWidget->addTab(addToTabWidget, newTabName); //Add plot to scan tree QTreeWidgetItem * plotTreeItemP = new QTreeWidgetItem(plotTreeItemDS); // X plotTreeItemP->setText(0, "Plot " + QString::number(plotTreeItemDS->childCount()) + " (" + QString::fromStdString(showMe->getName()) + ")"); plotTreeItemDS->addChild(plotTreeItemP); if(dynamic_cast<Histo2d*>(showMe) != nullptr){ Histo2d * myHist2d = dynamic_cast<Histo2d*>(showMe); //Create plot QCPColorMap * colorMap = new QCPColorMap(tabScanPlot->xAxis, tabScanPlot->yAxis); QCPColorScale * colorScale = new QCPColorScale(tabScanPlot); tabScanPlot->addPlottable(colorMap); tabScanPlot->plotLayout()->insertRow(0); tabScanPlot->plotLayout()->addElement(0, 0, new QCPPlotTitle(tabScanPlot, QString::fromStdString(myHist2d->getName()))); colorMap->setName(QString::fromStdString(myHist2d->getName())); colorMap->data()->setSize(80, 336); colorMap->data()->setRange(QCPRange(0, 80), QCPRange(0, 336)); colorMap->keyAxis()->setLabel(QString::fromStdString(myHist2d->getXaxisTitle())); colorMap->valueAxis()->setLabel(QString::fromStdString(myHist2d->getYaxisTitle())); for(int xCoord = 0; xCoord<80; xCoord++){ for(int yCoord = 0; yCoord<336; yCoord++){ double colVal = myHist2d->getBin(yCoord + 336*xCoord); //TODO make better colorMap->data()->setCell(xCoord, yCoord, colVal); } } tabScanPlot->plotLayout()->addElement(1, 1, colorScale); colorScale->setType(QCPAxis::atRight); colorMap->setColorScale(colorScale); colorScale->axis()->setLabel(QString::fromStdString(myHist2d->getZaxisTitle())); colorMap->setGradient(QCPColorGradient::gpPolar); colorMap->rescaleDataRange(); }else if(dynamic_cast<Histo1d*>(showMe) != nullptr){ Histo1d * myHist1d = dynamic_cast<Histo1d*>(showMe); QCPBars * myBars = new QCPBars(tabScanPlot->xAxis, tabScanPlot->yAxis); tabScanPlot->addPlottable(myBars); myBars->setName(QString::fromStdString(myHist1d->getName())); for(unsigned int i = 0; i < myHist1d->size(); i++) { myBars->addData((double)(i+1), myHist1d->getBin(i)); } myBars->rescaleAxes(); tabScanPlot->plotLayout()->insertRow(0); tabScanPlot->plotLayout()->addElement(0, 0, new QCPPlotTitle(tabScanPlot, QString::fromStdString(myHist1d->getName()))); myBars->keyAxis()->setLabel(QString::fromStdString(myHist1d->getXaxisTitle())); myBars->valueAxis()->setLabel(QString::fromStdString(myHist1d->getYaxisTitle())); }else{ std::cerr << "Correct plot type not found or severe cast error\n"; //DEBUG return; } tabScanPlot->rescaleAxes(); tabScanPlot->replot(); } ui->scanProgressBar->setValue(ui->scanProgressBar->value() + (int)(100.0/(7.0*N*M))); //7 delete fe->histogrammer; fe->histogrammer = nullptr; delete fe->ana; fe->ana = nullptr; } std::cout.rdbuf(coutBuf); std::cerr.rdbuf(cerrBuf); tmpOfCout->close(); tmpOfCerr->close(); std::ifstream tmpInCout("deleteMeCout.txt"); std::ifstream tmpInCerr("deleteMeCerr.txt"); std::cout << tmpInCout.rdbuf(); std::cerr << tmpInCerr.rdbuf(); tmpInCout.close(); tmpInCerr.close(); return; }
int main(int argc, char *argv[]) { std::cout << "#####################################" << std::endl; std::cout << "# Welcome to the YARR Scan Console! #" << std::endl; std::cout << "#####################################" << std::endl; std::cout << "-> Parsing command line parameters ..." << std::endl; // Init parameters unsigned specNum = 0; std::string scanType = "digitalscan"; std::string configPath = ""; std::string outputDir = "./"; bool doPlots = false; int c; while ((c = getopt(argc, argv, "hs:n:c:po:")) != -1) { switch (c) { case 'h': printHelp(); return 0; break; case 's': scanType = std::string(optarg); break; case 'n': specNum = atoi(optarg); break; case 'c': configPath = optarg; break; case 'p': doPlots = true; break; case 'o': outputDir = std::string(optarg); if (outputDir.back() != '/') outputDir = outputDir + "/"; break; case '?': if (optopt == 's' || optopt == 'n' || optopt == 'c') { std::cerr << "-> Option " << (char)optopt << " requires a parameter! (Proceeding with default)" << std::endl; } else { std::cerr << "-> Unknown parameter: " << (char)optopt << std::endl; } break; default: std::cerr << "-> Error while parsing command line parameters!" << std::endl; return -1; } } std::cout << " SPEC Nr: " << specNum << std::endl; std::cout << " Scan Type: " << scanType << std::endl; std::cout << " Global configuration: " << configPath << std::endl; std::cout << " Output Plots: " << doPlots << std::endl; std::cout << " Output Directory: " << outputDir << std::endl; std::cout << std::endl; std::cout << "#################" << std::endl; std::cout << "# Init Hardware #" << std::endl; std::cout << "#################" << std::endl; std::cout << "-> Init SPEC " << specNum << " : " << std::endl; SpecController spec(specNum); TxCore tx(&spec); RxCore rx(&spec); Bookkeeper bookie(&tx, &rx); bookie.setTargetThreshold(1500); std::cout << "-> Read global config (" << configPath << "):" << std::endl; std::fstream gConfig(configPath, std::ios::in); if (!gConfig) { std::cerr << "## ERROR ## Could not open file: " << configPath << std::endl; return -1; } while (!gConfig.eof() && gConfig) { unsigned id, tx, rx; std::string name, feCfgPath; char peekaboo = gConfig.peek(); if (peekaboo == '\n') { gConfig.ignore(); peekaboo = gConfig.peek(); } if (peekaboo == '#') { char tmp[1024]; gConfig.getline(tmp, 1024); std::cout << " Skipping: " << tmp << std::endl; } else { gConfig >> name >> id >> tx >> rx >> feCfgPath; if (gConfig.eof()) break; std::cout << "-> Found FE " << name << std::endl; // Add FE to bookkeeper bookie.addFe(id, tx, rx); bookie.getLastFe()->setName(name); // TODO verify cfg typea // Load config bookie.getLastFe()->fromFileBinary(feCfgPath); // Set chipId again after loading in case we got std cfg bookie.getLastFe()->setChipId(id); } } std::cout << std::endl; std::cout << "#################" << std::endl; std::cout << "# Configure FEs #" << std::endl; std::cout << "#################" << std::endl; std::chrono::steady_clock::time_point cfg_start = std::chrono::steady_clock::now(); for (unsigned i=0; i<bookie.feList.size(); i++) { Fei4 *fe = bookie.feList[i]; std::cout << "-> Configuring " << fe->getName() << std::endl; // Select correct channel tx.setCmdEnable(0x1 << fe->getTxChannel()); // Configure fe->configure(); fe->configurePixels(); // TODO should call abstract configure only // Wait for fifo to be empty std::this_thread::sleep_for(std::chrono::microseconds(100)); while(!tx.isCmdEmpty()); } std::chrono::steady_clock::time_point cfg_end = std::chrono::steady_clock::now(); std::cout << "-> All FEs configured in " << std::chrono::duration_cast<std::chrono::milliseconds>(cfg_end-cfg_start).count() << " ms !" << std::endl; // Wait for rx to sync with FE stream // TODO Check RX sync std::this_thread::sleep_for(std::chrono::microseconds(1000)); // Enable all active channels tx.setCmdEnable(bookie.getTxMask()); std::cout << "-> Setting Tx Mask to: 0x" << std::hex << bookie.getTxMask() << std::dec << std::endl; rx.setRxEnable(bookie.getRxMask()); std::cout << "-> Setting Rx Mask to: 0x" << std::hex << bookie.getRxMask() << std::dec << std::endl; std::cout << std::endl; std::cout << "##############" << std::endl; std::cout << "# Setup Scan #" << std::endl; std::cout << "##############" << std::endl; // TODO Make this nice ScanBase *s = NULL; std::cout << "-> Selecting Scan: " << scanType << std::endl; if (scanType == "digitalscan") { std::cout << "-> Found Digital Scan" << std::endl; s = new Fei4DigitalScan(&bookie); } else if (scanType == "analogscan") { std::cout << "-> Found Analog Scan" << std::endl; s = new Fei4AnalogScan(&bookie); } else if (scanType == "thresholdscan") { std::cout << "-> Found Threshold Scan" << std::endl; s = new Fei4ThresholdScan(&bookie); } else if (scanType == "totscan") { std::cout << "-> Found ToT Scan" << std::endl; s = new Fei4TotScan(&bookie); } else if (scanType == "tune_globalthreshold") { std::cout << "-> Found Global Threshold Tuning" << std::endl; s = new Fei4GlobalThresholdTune(&bookie); } else if (scanType == "tune_pixelthreshold") { std::cout << "-> Found Pixel Threshold Tuning" << std::endl; s = new Fei4PixelThresholdTune(&bookie); } else if (scanType == "tune_globalpreamp") { std::cout << "-> Found Global Preamp Tuning" << std::endl; s = new Fei4GlobalPreampTune(&bookie); } else if (scanType == "tune_pixelpreamp") { std::cout << "-> Found Pixel Preamp Tuning" << std::endl; s = new Fei4PixelPreampTune(&bookie); } else if (scanType == "noisescan") { std::cout << "-> Found Noisescan" << std::endl; s = new Fei4NoiseScan(&bookie); } else { std::cout << "-> No matching Scan found, possible:" << std::endl; listScans(); std::cerr << "-> Aborting!" << std::endl; return -1; } // Init histogrammer and analysis for (unsigned i=0; i<bookie.feList.size(); i++) { Fei4 *fe = bookie.feList[i]; if (fe->isActive()) { // Init histogrammer per FE fe->histogrammer = new Fei4Histogrammer(); fe->histogrammer->connect(fe->clipDataFei4, fe->clipHisto); // Add generic histograms fe->histogrammer->addHistogrammer(new OccupancyMap()); fe->histogrammer->addHistogrammer(new TotMap()); fe->histogrammer->addHistogrammer(new Tot2Map()); fe->histogrammer->addHistogrammer(new L1Dist()); fe->histogrammer->addHistogrammer(new HitDist()); // Init analysis per FE and depending on scan type fe->ana = new Fei4Analysis(&bookie, fe->getRxChannel()); fe->ana->connect(s, fe->clipHisto, fe->clipResult); fe->ana->addAlgorithm(new L1Analysis()); if (scanType == "digitalscan") { fe->ana->addAlgorithm(new OccupancyAnalysis()); } else if (scanType == "analogscan") { fe->ana->addAlgorithm(new OccupancyAnalysis()); } else if (scanType == "thresholdscan") { fe->ana->addAlgorithm(new ScurveFitter()); } else if (scanType == "totscan") { fe->ana->addAlgorithm(new TotAnalysis()); } else if (scanType == "tune_globalthreshold") { fe->ana->addAlgorithm(new OccGlobalThresholdTune()); } else if (scanType == "tune_pixelthreshold") { fe->ana->addAlgorithm(new OccPixelThresholdTune()); } else if (scanType == "tune_globalpreamp") { fe->ana->addAlgorithm(new TotAnalysis()); } else if (scanType == "tune_pixelpreamp") { fe->ana->addAlgorithm(new TotAnalysis()); } else if (scanType == "noisescan") { fe->ana->addAlgorithm(new NoiseAnalysis()); } else { std::cout << "-> Analyses not defined for scan type" << std::endl; listScans(); std::cerr << "-> Aborting!" << std::endl; return -1; } } } std::cout << "-> Running pre scan!" << std::endl; s->init(); s->preScan(); unsigned int numThreads = std::thread::hardware_concurrency(); std::cout << "-> Starting " << numThreads << " processor Threads:" << std::endl; std::vector<std::thread> procThreads; for (unsigned i=0; i<numThreads; i++) { procThreads.push_back(std::thread(process, &bookie)); std::cout << " -> Processor thread #" << i << " started!" << std::endl; } std::vector<std::thread> anaThreads; std::cout << "-> Starting histogrammer and analysis threads:" << std::endl; for (unsigned i=0; i<bookie.feList.size(); i++) { Fei4 *fe = bookie.feList[i]; if (fe->isActive()) { anaThreads.push_back(std::thread(analysis, fe->histogrammer, fe->ana)); std::cout << " -> Analysis thread of Fe " << fe->getRxChannel() << std::endl; } } std::cout << std::endl; std::cout << "########" << std::endl; std::cout << "# Scan #" << std::endl; std::cout << "########" << std::endl; std::cout << "-> Starting scan!" << std::endl; std::chrono::steady_clock::time_point scan_start = std::chrono::steady_clock::now(); s->run(); s->postScan(); std::cout << "-> Scan done!" << std::endl; scanDone = true; std::chrono::steady_clock::time_point scan_done = std::chrono::steady_clock::now(); std::cout << "-> Waiting for processors to finish ..." << std::endl; for (unsigned i=0; i<numThreads; i++) { procThreads[i].join(); } std::chrono::steady_clock::time_point processor_done = std::chrono::steady_clock::now(); processorDone = true; std::cout << "-> Processor done, waiting for analysis ..." << std::endl; for (unsigned i=0; i<anaThreads.size(); i++) { anaThreads[i].join(); } std::chrono::steady_clock::time_point all_done = std::chrono::steady_clock::now(); std::cout << "-> All done!" << std::endl; tx.setCmdEnable(0x0); rx.setRxEnable(0x0); std::cout << std::endl; std::cout << "##########" << std::endl; std::cout << "# Timing #" << std::endl; std::cout << "##########" << std::endl; std::cout << "-> Configuration: " << std::chrono::duration_cast<std::chrono::milliseconds>(cfg_end-cfg_start).count() << " ms" << std::endl; std::cout << "-> Scan: " << std::chrono::duration_cast<std::chrono::milliseconds>(scan_done-scan_start).count() << " ms" << std::endl; std::cout << "-> Processing: " << std::chrono::duration_cast<std::chrono::milliseconds>(processor_done-scan_done).count() << " ms" << std::endl; std::cout << "-> Analysis: " << std::chrono::duration_cast<std::chrono::milliseconds>(all_done-processor_done).count() << " ms" << std::endl; std::cout << std::endl; std::cout << "###########" << std::endl; std::cout << "# Cleanup #" << std::endl; std::cout << "###########" << std::endl; // Cleanup delete s; for (unsigned i=0; i<bookie.feList.size(); i++) { Fei4 *fe = bookie.feList[i]; if (fe->isActive()) { // Save config std::cout << "-> Saving config of FE " << fe->getName() << std::endl; fe->toFileBinary(); // Plot if (doPlots) { std::cout << "-> Plotting histograms of FE " << fe->getRxChannel() << std::endl; fe->ana->plot("ch" + std::to_string(fe->getRxChannel()) + "_" + scanType, outputDir); } // Free delete fe->histogrammer; fe->histogrammer = NULL; delete fe->ana; fe->ana = NULL; } } return 0; }