diff --git a/slsDetectorGui/include/qDrawPlot.h b/slsDetectorGui/include/qDrawPlot.h index 35068feb6..4d975071f 100644 --- a/slsDetectorGui/include/qDrawPlot.h +++ b/slsDetectorGui/include/qDrawPlot.h @@ -118,6 +118,10 @@ private: /** Timer to update plot */ QTimer* plot_update_timer; + /** Timer to pause getting data from client */ + QTimer* data_pause_timer; + bool data_pause_over; + /** 1D object */ SlsQt1DPlot* plot1D; @@ -217,7 +221,9 @@ private: double timerValue; /** every nth frame when to plot */ int frameFactor; - bool plotLock; + /** old data that did not get lock(for frame factor)**/ + bool oldCopy; + int oldFrameNumber; /**if frame is enabled in measurement tab */ bool isFrameEnabled; /**if trigger is enabled in measurement tab */ @@ -291,7 +297,7 @@ void StartDaq(bool start); * @param id is the id of the clone */ void CloneCloseEvent(int id); - +void UpdatePause(){data_pause_over=true;}; signals: void UpdatingPlotFinished(); diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 66ec00d22..55acabb09 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -4,20 +4,20 @@ * Created on: May 7, 2012 * Author: Ian Johnson */ -/** Qt Project Class Headers */ +// Qt Project Class Headers #include "qDrawPlot.h" #include "qCloneWidget.h" #include "slsDetector.h" -/** Project Class Headers */ +// Project Class Headers #include "slsDetector.h" #include "multiSlsDetector.h" #include "postProcessing.h" -/** Qt Include Headers */ +// Qt Include Headers #include #include #include #include -/** C++ Include Headers */ +// C++ Include Headers #include #include #include @@ -37,7 +37,7 @@ qDrawPlot::qDrawPlot(QWidget *parent,multiSlsDetector*& detector): //------------------------------------------------------------------------------------------------------------------------------------------------- qDrawPlot::~qDrawPlot(){ - /** Clear plot*/ + // Clear plot Clear1DPlot(); for(QVector::iterator h = plot1D_hists.begin();h!=plot1D_hists.end();h++) delete *h; plot1D_hists.clear(); @@ -58,9 +58,9 @@ void qDrawPlot::SetupWidgetWindow(){ stop_signal = 0; pthread_mutex_init(&last_image_complete_mutex,NULL); //gui_acquisition_thread_running = 0; - /** Default Plotting*/ + // Default Plotting plot_in_scope = 0; - /**2d*/ + //2d lastImageNumber = 0; last_plot_number = 0; @@ -68,7 +68,7 @@ void qDrawPlot::SetupWidgetWindow(){ lastImageArray = 0; image_data = 0; - /**1d*/ + //1d nHists = 0; histNBins = 0; histXAxis = 0; @@ -79,18 +79,20 @@ void qDrawPlot::SetupWidgetWindow(){ XYRangeChanged = false; timerValue = PLOT_TIMER_MS; frameFactor=0; - plotLock = false; + oldCopy = false; + oldFrameNumber = 0; + data_pause_over = true;//to get the first image isFrameEnabled = false; isTriggerEnabled = false; - /** This is so that it initially stop and plots */ + // This is so that it initially stop and plots running = 1; for(int i=0;isetLayout(layout); @@ -100,9 +102,10 @@ void qDrawPlot::SetupWidgetWindow(){ boxPlot->setFont(QFont("Sans Serif",11,QFont::Normal)); plot_update_timer = new QTimer(this); connect(plot_update_timer, SIGNAL(timeout()), this, SLOT(UpdatePlot())); + data_pause_timer = new QTimer(this); + connect(data_pause_timer, SIGNAL(timeout()), this, SLOT(UpdatePause())); - - /** Default titles- only for the initial picture*/ + // Default titles- only for the initial picture histXAxisTitle="Channel Number"; histYAxisTitle="Counts"; @@ -118,7 +121,7 @@ void qDrawPlot::SetupWidgetWindow(){ - /** setting default plot titles and settings*/ + // setting default plot titles and settings plot1D = new SlsQt1DPlot(boxPlot); plot1D->setFont(QFont("Sans Serif",9,QFont::Normal)); plot1D->SetXTitle(histXAxisTitle.toAscii().constData()); @@ -163,11 +166,15 @@ void qDrawPlot::StartStopDaqToggle(bool stop_if_running){ running=!running; }else if(!stop_if_running){ //then start - /**Do the following only once before each n measurements */ - /** Reset Current Measurement */ + //Do the following only once before each n measurements + // Reset Current Measurement currentMeasurement = 0; emit SetCurrentMeasurementSignal(currentMeasurement); - /** Number of Exposures */ + + //to get the first image + data_pause_over = true; + + // Number of Exposures int numFrames = (isFrameEnabled)*((int)myDet->setTimer(slsDetectorDefs::FRAME_NUMBER,-1)); int numTriggers = (isTriggerEnabled)*((int)myDet->setTimer(slsDetectorDefs::CYCLES_NUMBER,-1)); @@ -176,10 +183,10 @@ void qDrawPlot::StartStopDaqToggle(bool stop_if_running){ number_of_exposures= numFrames * numTriggers; cout<<"\tNumber of Exposures:"<setTimer(slsDetectorDefs::ACQUISITION_TIME,-1))*1E-9); cout<<"\tExposure Time:"<setTimer(slsDetectorDefs::FRAME_PERIOD,-1))*1E-9); cout<<"\tAcquisition Period:"<registerDataCallback(&(GetDataCallBack),this); - /** Start acquiring data from server */ + // Start acquiring data from server if(!firstTime) pthread_join(gui_acquisition_thread,NULL);//wait until he's finished, ie. exits pthread_create(&gui_acquisition_thread, NULL,DataStartAcquireThread, (void*) this); firstTime = false; - /** This is set here and later reset to zero when all the plotting is done - * This is manually done instead of keeping track of thread because - * this thread returns immediately after executing the acquire command*/ + // This is set here and later reset to zero when all the plotting is done + // This is manually done instead of keeping track of thread because + // this thread returns immediately after executing the acquire command gui_acquisition_thread_running=1; cout<<"Started acquiring threaddd:"<progressIndex; - + //not frame factor + if(!frameFactor){ + //if the time is not over, RETURN + if(!data_pause_over){ + //lastImageNumber= currentFrame+1; + currentFrame++; + return 0; + } + data_pause_over=false; + data_pause_timer->start((int)(PLOT_TIMER_MS/2)); + }//if frame factor or last frame of last measurement... for all other factors, RETURN + else{ + if(((currentFrame+1==number_of_exposures)&&(currentMeasurement+1==number_of_measurements)) + ||(!((currentFrame)%frameFactor))) + oldCopy = false;//if this works, then we forget old data + else{ + //lastImageNumber= currentFrame+1; + currentFrame++; + progress=(int)data->progressIndex; + //if theres an old copy, try to get lock again + if(oldCopy){ +#ifdef VERBOSE + cout<<"Copying old data: "<0;i--) + memcpy(histYAxis[i],yvalues[i-1],nPixelsX*sizeof(double)); + memcpy(histYAxis[0],yvalues[0],nPixelsX*sizeof(double)); + }//2d + else{ + // Titles + sprintf(temp_title,"Image Number %d",oldFrameNumber); + imageTitle = temp_title; + // copy data + //memcpy(lastImageArray,image_data,nPixelsX*nPixelsY*sizeof(double)); + } + pthread_mutex_unlock(&(last_image_complete_mutex)); + } + } + return 0; + } + } + //if plot disabled, RETURN if(!plotEnable) { - lastImageNumber= currentFrame+1; + progress=(int)data->progressIndex; + //lastImageNumber= currentFrame+1; currentFrame++; return 0; } - - /** Get data from client */ - /**1d*/ - if(plot_in_scope==1){ - /** Persistency */ - if(currentPersistency < persistency)currentPersistency++; - else currentPersistency=persistency; - for(int i=currentPersistency;i>0;i--) - memcpy(yvalues[i],yvalues[i-1],nPixelsX*sizeof(double)); - nHists = currentPersistency+1; - memcpy(yvalues[0],data->values,nPixelsX*sizeof(double)); - //for(int i=0;i<(int)nPixelsX;i++) *(yvalues[0]+i) = (double)*(data->values+i); - } - /**2d*/ - else{ - for(unsigned int px=0;pxprogressIndex; if((currentFrame)<(number_of_exposures)){ #ifdef VERYVERBOSE - cout<<"Reading in image: "<0;i--) - memcpy(histYAxis[i],histYAxis[i-1],nPixelsX*sizeof(double)); - memcpy(histYAxis[0],yvalues[0],nPixelsX*sizeof(double)); - } - /**2d*/ - else{ - sprintf(temp_title,"Image Number %d",currentFrame); imageTitle = temp_title; - memcpy(lastImageArray,image_data,nPixelsX*nPixelsY*sizeof(double)); - } - pthread_mutex_unlock(&(last_image_complete_mutex)); + //1d + if(plot_in_scope==1){ + // Titles + sprintf(temp_title,"Frame %d",currentFrame); histTitle[0] = temp_title; + // Persistency + if(currentPersistency < persistency)currentPersistency++; + else currentPersistency=persistency; + nHists = currentPersistency+1; + // copy data + //memcpy(histXAxis, xvalues,nPixelsX*sizeof(double)); + for(int i=currentPersistency;i>0;i--) + memcpy(histYAxis[i],histYAxis[i-1],nPixelsX*sizeof(double)); + memcpy(histYAxis[0],data->values,nPixelsX*sizeof(double)); + //for(int i=0;i<(int)nPixelsX;i++) *(yvalues[0]+i) = (double)*(data->values+i); + } + //2d + else{ + // Titles + sprintf(temp_title,"Image Number %d",currentFrame); + imageTitle = temp_title; + // manufacture data for now + for(unsigned int px=0;pxvalues,nPixelsX*nPixelsY*sizeof(double)); + } + pthread_mutex_unlock(&(last_image_complete_mutex)); + }//copies old data only if its frame factor + else if(frameFactor){ + oldCopy = true; + oldFrameNumber = currentFrame; + //1D + if(plot_in_scope==1){ + // Persistency + if(currentPersistency < persistency)currentPersistency++; + else currentPersistency=persistency; + nHists = currentPersistency+1; + // copy old data + for(int i=currentPersistency;i>0;i--) + memcpy(yvalues[i],yvalues[i-1],nPixelsX*sizeof(double)); + nHists = currentPersistency+1; + memcpy(yvalues[0],data->values,nPixelsX*sizeof(double)); + }//2D + else{ + // copy old data + //memcpy(image_data,data->values,nPixelsX*nPixelsY*sizeof(double)); } } currentFrame++; } - /** To make sure plotting locks parameters until it has plotted */ - if(frameFactor){ - if(currentFrame==number_of_exposures) plotLock = true; - else if(!((currentFrame-1)%frameFactor)) plotLock = true; - } } #ifdef VERYVERBOSE cout<<"Exiting GetData function"<stop(); - /** only if no plot isnt enabled */ + // only if no plot isnt enabled if(plotEnable){ - /** It doesnt go in here only if nth frame plotting in on and its not the nth frame*/ - if(canPlot){ - LockLastImageArray(); - /**1-d plot stuff */ - if(lastImageNumber){ - if(histNBins){ + LockLastImageArray(); + //1-d plot stuff + if(lastImageNumber){ + if(histNBins){ #ifdef VERYVERBOSE - cout<<"Last Image Number: "<SetXTitle(histXAxisTitle.toAscii().constData()); - plot1D->SetYTitle(histYAxisTitle.toAscii().constData()); - for(int hist_num=0;hist_num<(int)nHists;hist_num++){ - SlsQtH1D* h; - if(hist_num+1>plot1D_hists.size()){ - plot1D_hists.append(h=new SlsQtH1D("1d plot",histNBins,histXAxis,GetHistYAxis(hist_num))); - h->SetLineColor(hist_num+1); - }else{ - h=plot1D_hists.at(hist_num); - h->SetData(histNBins,histXAxis,GetHistYAxis(hist_num)); - } - h->setTitle(GetHistTitle(hist_num)); - h->Attach(plot1D); - + Clear1DPlot(); + plot1D->SetXTitle(histXAxisTitle.toAscii().constData()); + plot1D->SetYTitle(histYAxisTitle.toAscii().constData()); + for(int hist_num=0;hist_num<(int)nHists;hist_num++){ + SlsQtH1D* h; + if(hist_num+1>plot1D_hists.size()){ + plot1D_hists.append(h=new SlsQtH1D("1d plot",histNBins,histXAxis,GetHistYAxis(hist_num))); + h->SetLineColor(hist_num+1); + }else{ + h=plot1D_hists.at(hist_num); + h->SetData(histNBins,histXAxis,GetHistYAxis(hist_num)); } - /** update range if required */ - if(XYRangeChanged){ - if(!IsXYRange[qDefs::XMINIMUM]) - XYRangeValues[qDefs::XMINIMUM]= plot1D->GetXMinimum(); - if(!IsXYRange[qDefs::XMAXIMUM]) - XYRangeValues[qDefs::XMAXIMUM]= plot1D->GetXMaximum(); - if(!IsXYRange[qDefs::YMINIMUM]) - XYRangeValues[qDefs::YMINIMUM]= plot1D->GetYMinimum(); - if(!IsXYRange[qDefs::YMAXIMUM]) - XYRangeValues[qDefs::YMAXIMUM]= plot1D->GetYMaximum(); + h->setTitle(GetHistTitle(hist_num)); + h->Attach(plot1D); - plot1D->SetXMinMax(XYRangeValues[qDefs::XMINIMUM],XYRangeValues[qDefs::XMAXIMUM]); - plot1D->SetYMinMax(XYRangeValues[qDefs::YMINIMUM],XYRangeValues[qDefs::YMAXIMUM]); - - XYRangeChanged = false; - } - plotLock = false; } - } - /**2-d plot stuff */ - if(lastImageArray){ - if(lastImageNumber&&last_plot_number!=(int)lastImageNumber && //there is a new plot - nPixelsX>0&&nPixelsY>0){ - plot2D->GetPlot()->SetData(nPixelsX,-0.5,nPixelsX-0.5,nPixelsY,-0.5,nPixelsY-0.5,lastImageArray); - plot2D->setTitle(GetImageTitle()); - plot2D->SetXTitle(imageXAxisTitle); - plot2D->SetYTitle(imageYAxisTitle); - plot2D->SetZTitle(imageZAxisTitle); - plot2D->UpdateNKeepSetRangeIfSet(); //this will keep a "set" z range, and call Plot()->Update(); - } - /** update range if required */ + // update range if required if(XYRangeChanged){ if(!IsXYRange[qDefs::XMINIMUM]) - XYRangeValues[qDefs::XMINIMUM]= plot2D->GetPlot()->GetXMinimum(); + XYRangeValues[qDefs::XMINIMUM]= plot1D->GetXMinimum(); if(!IsXYRange[qDefs::XMAXIMUM]) - XYRangeValues[qDefs::XMAXIMUM]= plot2D->GetPlot()->GetXMaximum(); + XYRangeValues[qDefs::XMAXIMUM]= plot1D->GetXMaximum(); if(!IsXYRange[qDefs::YMINIMUM]) - XYRangeValues[qDefs::YMINIMUM]= plot2D->GetPlot()->GetYMinimum(); + XYRangeValues[qDefs::YMINIMUM]= plot1D->GetYMinimum(); if(!IsXYRange[qDefs::YMAXIMUM]) - XYRangeValues[qDefs::YMAXIMUM]= plot2D->GetPlot()->GetYMaximum(); + XYRangeValues[qDefs::YMAXIMUM]= plot1D->GetYMaximum(); - plot2D->GetPlot()->SetXMinMax(XYRangeValues[qDefs::XMINIMUM],XYRangeValues[qDefs::XMAXIMUM]); - plot2D->GetPlot()->SetYMinMax(XYRangeValues[qDefs::YMINIMUM],XYRangeValues[qDefs::YMAXIMUM]); + plot1D->SetXMinMax(XYRangeValues[qDefs::XMINIMUM],XYRangeValues[qDefs::XMAXIMUM]); + plot1D->SetYMinMax(XYRangeValues[qDefs::YMINIMUM],XYRangeValues[qDefs::YMAXIMUM]); XYRangeChanged = false; } - plotLock = false; + } + } + //2-d plot stuff + if(lastImageArray){ + if(lastImageNumber&&last_plot_number!=(int)lastImageNumber && //there is a new plot + nPixelsX>0&&nPixelsY>0){ + plot2D->GetPlot()->SetData(nPixelsX,-0.5,nPixelsX-0.5,nPixelsY,-0.5,nPixelsY-0.5,lastImageArray); + plot2D->setTitle(GetImageTitle()); + plot2D->SetXTitle(imageXAxisTitle); + plot2D->SetYTitle(imageYAxisTitle); + plot2D->SetZTitle(imageZAxisTitle); + plot2D->UpdateNKeepSetRangeIfSet(); //this will keep a "set" z range, and call Plot()->Update(); + } + // update range if required + if(XYRangeChanged){ + if(!IsXYRange[qDefs::XMINIMUM]) + XYRangeValues[qDefs::XMINIMUM]= plot2D->GetPlot()->GetXMinimum(); + if(!IsXYRange[qDefs::XMAXIMUM]) + XYRangeValues[qDefs::XMAXIMUM]= plot2D->GetPlot()->GetXMaximum(); + if(!IsXYRange[qDefs::YMINIMUM]) + XYRangeValues[qDefs::YMINIMUM]= plot2D->GetPlot()->GetYMinimum(); + if(!IsXYRange[qDefs::YMAXIMUM]) + XYRangeValues[qDefs::YMAXIMUM]= plot2D->GetPlot()->GetYMaximum(); + + plot2D->GetPlot()->SetXMinMax(XYRangeValues[qDefs::XMINIMUM],XYRangeValues[qDefs::XMAXIMUM]); + plot2D->GetPlot()->SetYMinMax(XYRangeValues[qDefs::YMINIMUM],XYRangeValues[qDefs::YMAXIMUM]); + + XYRangeChanged = false; } } } last_plot_number=lastImageNumber; if(plotEnable) UnlockLastImageArray(); - /** Measurement not over, continue*/ + // Measurement not over, continue if(number_of_exposures!=currentFrame){//las plot number? - /**if the interval is a timer and not nth frame **/ + //if the interval is a timer and not nth frame * if(!frameFactor) plot_update_timer->start((int)timerValue); else plot_update_timer->start((int)PLOT_TIMER_MS); } - /** if a measurement is over */ + // if a measurement is over else{ currentMeasurement++; - /** if all the measurements are over */ + // if all the measurements are over if(currentMeasurement==number_of_measurements){ - plotLock = false; StartStopDaqToggle(true); emit UpdatingPlotFinished(); - }/** To start the next measurement*/ + }// To start the next measurement else{ - plotLock = false; emit SetCurrentMeasurementSignal(currentMeasurement); StopDaqForGui(); StartDaq(true); @@ -521,15 +578,15 @@ void qDrawPlot::ClonePlot(){ found=true; break; } - /** no space for more clone widget references*/ + // no space for more clone widget references if(!found){ cout<<"Too many clones"<title(),(int)plot_in_scope,plot1D,plot2D,myDet->getFilePath()); if(plot_in_scope==1){ plot1D = new SlsQt1DPlot(boxPlot); @@ -551,14 +608,14 @@ void qDrawPlot::ClonePlot(){ setMinimumHeight(preheight); resize(width(),preheight); - /** update the actual plot only if running, else it doesnt know when its over*/ + // update the actual plot only if running, else it doesnt know when its over if(running) UpdatePlot(); connect(this, SIGNAL(InterpolateSignal(bool)), plot2D, SIGNAL(InterpolateSignal(bool))); connect(this, SIGNAL(ContourSignal(bool)), plot2D, SIGNAL(ContourSignal(bool))); connect(this, SIGNAL(LogzSignal(bool)), plot2D, SLOT(SetZScaleToLog(bool))); winClone[i]->show(); - /** to remember which all clone widgets were closed*/ + // to remember which all clone widgets were closed connect(winClone[i], SIGNAL(CloneClosedSignal(int)),this, SLOT(CloneCloseEvent(int))); } @@ -583,12 +640,12 @@ void qDrawPlot::CloneCloseEvent(int id){ //------------------------------------------------------------------------------------------------------------------------------------------------- void qDrawPlot::SavePlot(){ - /** render image */ + // render image QImage savedImage(size().width(),size().height(),QImage::Format_RGB32); QPainter painter(&savedImage); render(&painter); - /** save image*/ + // save image QString fName = QString(myDet->getFilePath().c_str())+"/Image.png"; fName = QFileDialog::getSaveFileName(0,tr("Save Image"),fName,tr("PNG Files (*.png);;XPM Files(*.xpm);;JPEG Files(*.jpg)"),0,QFileDialog::ShowDirsOnly); @@ -618,8 +675,8 @@ void qDrawPlot::EnablePlot(bool enable){ cout<<"Plotting set to:"<stopAcquisition(); //btnStartStop->setStyleSheet("color:green"); diff --git a/slsDetectorGui/src/qTabPlot.cpp b/slsDetectorGui/src/qTabPlot.cpp index 6b98ef944..97f138418 100644 --- a/slsDetectorGui/src/qTabPlot.cpp +++ b/slsDetectorGui/src/qTabPlot.cpp @@ -422,7 +422,7 @@ void qTabPlot::SetFrequency(){ break; case 1: acqPeriodMS = (myDet->setTimer(slsDetectorDefs::FRAME_PERIOD,-1)*(1E-6)); - /** gets the acq period * number of frames*/ + /** gets the acq period * number of nth frames*/ timeMS = (spinNthFrame->value())*acqPeriodMS; /** To make sure the period between plotting is not less than minimum plot timer in ms*/ if(timeMS