//Function: Constructor //Description: Creates pointers to data structures contained by TwoPhotonGui to set up acquisition // Sets up Vision modules TwoPhotonThread::TwoPhotonThread(ScanEngine *scanEngi, AcqEngine *acqEngi, DataFile2P *data2Pi, zStepperDriver *zStepper, AomControl *aCtrl) { scanEng = scanEngi; acqEng = acqEngi; data2P = data2Pi; zStep = *zStepper; aomCtrl = aCtrl; Point toolPos; toolPos.x=850; toolPos.y=20; //temporary scaling scaleMin1 = 0; scaleMax1 = 32767; scaleMin2 = 0; scaleMax2 = 32767; //Setup diplay and display tools using NIVision calls image1 = imaqCreateImage(IMAQ_IMAGE_RGB, 0); displayWinNum1 = 1; imaqDisplayImage(image1, displayWinNum1, 1); imaqSetWindowTitle(1, "PMT Images"); imaqSetWindowSize(1, 256, 256); posWindow1.x = 850; posWindow1.y = 300; imaqMoveWindow(1, posWindow1); imaqShowToolWindow (TRUE); imaqMoveToolWindow(toolPos); imaqSetCurrentTool (IMAQ_POLYLINE_TOOL); image2 = imaqCreateImage(IMAQ_IMAGE_U8, 0); displayWinNum2 = 2; imaqDisplayImage(image2, displayWinNum2, 1); imaqSetWindowTitle(2, "ROI Images"); imaqSetWindowSize(2, 256, 256); posWindow2.x = 850; posWindow2.y = 590; imaqMoveWindow(2, posWindow2); intScalingCoeff = 1.0; bScaleCoeffCalc = false; //Allocate memory for display arrays. imageData1 = new RGBValue[acqEng->getnumValidXSamps() * acqEng->getnumValidYSamps()]; imageData2 = new unsigned char[acqEng->getWidth() * acqEng->getRepeats()]; bContinuous = false; bLifetimeFov = false; bLinescan = false; }
int CVICALLBACK Thresholding (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int threshold = 0; int histogram[256] = {0}; HistogramReport *report = NULL; switch (event) { case EVENT_COMMIT: GetCtrlVal (mypanel, MYPANEL_THRESHOLD_SLIDE, &threshold); imaqThreshold (destimage, sourimage, threshold, 255, TRUE, 255); imaqSetWindowTitle (1, "Picture after binaryzation"); imaqMoveWindow (1, imaqMakePoint (150, 260)); imaqDisplayImage (destimage, 1, TRUE); report = imaqHistogram (destimage, 256, 0, 255, IMAQ_IMAGE_U8); DeleteGraphPlot (mypanel, MYPANEL_MYGRAPH, -1, VAL_IMMEDIATE_DRAW); PlotY (mypanel, MYPANEL_MYGRAPH, (*report).histogram, 256, VAL_UNSIGNED_INTEGER, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED); break; } return 0; }
int CVICALLBACK Load_Picture (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { char picname[512] = {'\0'}; int ret = 0; HistogramReport *report = NULL; switch (event) { case EVENT_COMMIT: ret = FileSelectPopup ("", "*.*", "", "Load; select an image file", VAL_LOAD_BUTTON, 0, 0, 1, 0, picname); if (ret == 1) { imaqReadFile (sourimage, picname, NULL, NULL); imaqMoveWindow (0, imaqMakePoint (50, 260)); imaqDisplayImage (sourimage, 0, TRUE); report = imaqHistogram (sourimage, 256, 0, 255, IMAQ_IMAGE_U8); DeleteGraphPlot (mypanel, MYPANEL_MYGRAPH, -1, VAL_IMMEDIATE_DRAW); PlotY (mypanel, MYPANEL_MYGRAPH, (*report).histogram, 256, VAL_UNSIGNED_INTEGER, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED); } break; } return 0; }
int sgl_grab(CameraSgl *camera) { ImageInfo info; IMAQdxError error = 0; CameraData *data = &camera->data; int left = camera->rect_show.left; int top = camera->rect_show.top; if (sgl_is_opend(camera)) { error = IMAQdxGrab (camera->session_id, data->image, TRUE, &data->buffer_num); if (error) { goto ERROR_MSG; } if (camera->attached_win != NULL) { if (camera->visible) { imaqDisplayImage (camera->data.image, camera->display_win_num, FALSE); if (error) { goto ERROR_MSG; } // 获取额外的信息 imaqGetImageInfo (data->image, &info); imaqMoveWindow ( camera->display_win_num, MakePoint( left, top) ); imaqShowWindow (camera->display_win_num, TRUE); // printf("grab ---- visible\n"); } else { imaqShowWindow (camera->display_win_num, FALSE); // printf("grab ---- invisible\n"); } } } return 0; ERROR_MSG: sgl_camera_message_error(error, camera->error_callback); return -1; }
//Function: Run //Description: Runs acquisition routine in a new thread // This function cannot access gui widgets so all variables are frozen when thread class instance is created void AcqThread::run() { int error=0; TaskHandle digTaskHandle=0; bool done; int retVal; int numZSteps; int iZCount; int x1; int x2; int y1; int y2; int numValidXSamps; int numValidYSamps; double debug; //set to not be terminated (default) terminate = false; //scaling coeff has not been calculated for this acq yet bScaleCoeffCalc = false; //overscan values have not yet been calculated into the fov scanEng->setOverscanCalculated(false); done = false; do { //if regular acq (not line scan), call generateWaveForms if(!bLinescan) { scanEng->initScan(true,false); retVal = scanEng->generateWaveForms(); retVal = acqEng->initAcq(true,false); } else //Line scan mode { retVal = scanEng->initScan(true,true); if(!NIVisionCurrContourInfo) { emit sendMessageForPopup("Error","No data points defined\n"); goto Error; } if (NIVisionCurrContourInfo->type != IMAQ_LINE) { emit sendMessageForPopup("Error","Points must be defined with line tool\n"); goto Error; } //grab endpoints from line contour x1=NIVisionCurrContourInfo->structure.line->start.x; y1=NIVisionCurrContourInfo->structure.line->start.y; x2=NIVisionCurrContourInfo->structure.line->end.x; y2=NIVisionCurrContourInfo->structure.line->end.y; //Update data class data2P->Header.setLsX1(x1); data2P->Header.setLsX2(x2); data2P->Header.setLsY1(y1); data2P->Header.setLsY2(y2); //Calc the voltages that correspond to the x1,y1,x2,y2. These will define the line scan waveforms. double x1V,y1V,x2V,y2V; CalcXYVoltsFromPxlVal(x1, y1, x1V, y1V); scanEng->setROIPt1XVolts(x1V); scanEng->setROIPt1YVolts(y1V); CalcXYVoltsFromPxlVal(x2, y2, x2V, y2V); scanEng->setROIPt2XVolts(x2V); scanEng->setROIPt2YVolts(y2V); retVal = scanEng->generateLineScanWaveForms(); retVal = acqEng->initAcq(true,true); } //_____Setup for 3D Acq if needed_____ if (acqEng->getB3DAcq()) { numZSteps = this->CalcNumZSteps(); CalcIntensityScalingCoeff(); } else numZSteps = 1; //_____DAQmx DigOut Configure Code (Sample clock for Aout and Ain)____________________________________________ DAQmxErrChk (DAQmxCreateTask("SampleClockTask",&digTaskHandle)); DAQmxErrChk (DAQmxCreateCOPulseChanFreq (digTaskHandle, "/Dev1/ctr1", "SampleClock", DAQmx_Val_Hz, DAQmx_Val_Low, 0.1, scanEng->getSamp_Rate(), 0.5)); if (bLinescan) DAQmxErrChk (DAQmxCfgImplicitTiming(digTaskHandle,DAQmx_Val_ContSamps ,scanEng->getNumSampsPerFrame_LS())) else DAQmxErrChk (DAQmxCfgImplicitTiming(digTaskHandle,DAQmx_Val_ContSamps ,scanEng->getNumSampsPerFrame())) //_____config AOut task for triggered, finite samps_____ retVal = scanEng->configDAQmxTask(true, false); //_____Write samples to daq board_____ retVal = scanEng->writeDAQmxTask(); //_____Config AIn task for triggered, finite samps_____ retVal = acqEng->configDAQmxTask(true, false); pDone = 0; for (iZCount = 0; iZCount < numZSteps; iZCount++) { //Only if there are Z steps to do if(numZSteps>1) { //update Z Pos zStep.setDesiredZPos(acqEng->getZStartPos() + (acqEng->getZStepSize() * iZCount)); //if (zStep->getDesiredZPos() != acqEng->getZPos()) if(numZSteps!=1) zStep.MoveTo(zStep.getDesiredZPos(),zStep.getCurrentStepConvFactor()); //Manual zPos Calculations //acqEng->setZPos(acqEng->getZPos()+acqEng->getZStepSize()); acqEng->setZPos(zStep.getCurrentZPos()); emit sigZPosChange(zStep.getCurrentZPos()); //Update pDone for updating gui progress bar pDone = ((double)iZCount)/((double)numZSteps); emit sendProgress(pDone); //update gui field //TwoPhotonGui::doubleSpinBox_zPos->setValue(zStepEng->getCurrentZPos()); NEED IMPLEMENTATION //update acqEng field //acqEng->setZPos(zStep->getCurrentZPos()); NOTE: this isn't working, using manual z-pos calculations } //if Aom Voltage scaling is selected, update Aom if(aomCtrl->getBIntScaling()) { debug = CalcAomIntVoltage((acqEng->getZStartPos()-acqEng->getZPos())); AomUpdate(debug); //turns AOM on } else { AomUpdate(aomCtrl->getAomOnVoltage()); //Turns on AOM (no updating for depth) } //_____Start DAQmx Read._____ retVal = acqEng->startDAQmxTask(); //_____Start DAQmx write._____ retVal = scanEng->startDAQmxTask(); //_____Start DAQmx Trig._____ DAQmxErrChk (DAQmxStartTask(digTaskHandle)) //_____Perform read. Execution will pause until all samps acquired._____ retVal = acqEng->readDAQmxTask(); /* Added for diagnostics. I want to write out the acq buffer here before I flip even rows. */ /* NEED IMPLEMENTATION //_____Update Histogram._____ retVal = ProcessDataForHistogram(appState->acqStruct); if (appState->acqStruct.bInput1) DeleteGraphPlot (appState->panelHandle, PANEL_HIST1, -1, VAL_IMMEDIATE_DRAW); PlotXY (appState->panelHandle, PANEL_HIST1, appState->binsArray, appState->histArray1, NUM_BINS, VAL_SHORT_INTEGER, VAL_UNSIGNED_INTEGER, VAL_VERTICAL_BAR, VAL_SOLID_SQUARE, VAL_SOLID, 1, VAL_BLUE); if (appState->acqStruct.bInput2) DeleteGraphPlot (appState->panelHandle, PANEL_HIST2, -1, VAL_DELAYED_DRAW); PlotXY (appState->panelHandle, PANEL_HIST2, appState->binsArray, appState->histArray2, NUM_BINS, VAL_SHORT_INTEGER, VAL_UNSIGNED_INTEGER, VAL_VERTICAL_BAR, VAL_SOLID_SQUARE, VAL_SOLID, 1, VAL_BLUE); */ //Update image display retVal = ProcessDataForDisplay(bLinescan); if(!bLinescan) { numValidXSamps = (int)acqEng->getnumValidXSamps(); numValidYSamps = (int)acqEng->getnumValidYSamps(); if (!bLifetimeFov) { //Had to move imaq.. calls out of this thread. Wasn't updating when called from this thread. // using signal to notify other thread that new image data are in the image pointers. imaqArrayToImage(*ptrToimage1, *ptrToimageData1, (int)acqEng->getnumValidXSamps(),(int)acqEng->getnumValidYSamps()); imaqDisplayImage(*ptrToimage1, displayWinNum1, 1); //emit this->sigUdateVisionWindows(displayWinNum1,numValidXSamps,numValidYSamps); } } else { numValidXSamps = (int)acqEng->getWidth(); numValidYSamps = (int)acqEng->getRepeats(); if (!bLifetimeFov) { imaqArrayToImage(*ptrToimage2, *ptrToimageData2, (int)acqEng->getWidth(),(int)acqEng->getRepeats()); imaqDisplayImage(*ptrToimage2, displayWinNum2, 1); //emit this->sigUdateVisionWindows(displayWinNum2,numValidXSamps,numValidYSamps); } } //imaqHistogram(image1,65536,0,1,NULL); //Update Data2P class instance before writing it to file updateDataPtr(); //Save the data to file if requested if (acqEng->getSaveData()) { if(!bLinescan) { Update2PDataStruct(); if (acqEng->getBInput1()) retVal = data2P->WriteTheData(1,acqEng); if (acqEng->getBInput2()) retVal = data2P->WriteTheData(2,acqEng); } else //If linescan, need to record correct lineLength/lineRate { retVal =scanEng->calcLineLengthStruct(x1,y1,x2,y2); retVal =scanEng->calcLineRate(); Update2PDataStruct(); data2P->Header.setLineRate(data2P->Header.getLinescanRate()); //ensure linerate recorded is that of linescan if (acqEng->getBInput1()) retVal = data2P->WriteTheData(1,acqEng); if (acqEng->getBInput2()) retVal = data2P->WriteTheData(2,acqEng); } } DAQmxStopTask(digTaskHandle); retVal = acqEng->stopDAQmxTask(); retVal = scanEng->stopDAQmxTask(); //retVal = scanEng->clearDAQmxTask(); //scanEng->setScanTaskHandle(0); if(terminate) goto Kill; //turn off Aom until ready to image again (set to 0 volts) AomUpdate(0.0); aomCtrl->setAomOn(false); } Kill: retVal = scanEng->stopDAQmxTask(); //Cleanup ... // retVal = AcqEngineStopDAQmxTask(acqStruct); DAQmxClearTask(scanEng->getScanTaskHandle()); scanEng->setScanTaskHandle(0); // retVal = ScanEngineStopDAQmxTask(scanStruct); DAQmxClearTask(acqEng->getAcqTaskHandle()); acqEng->setAcqTaskHandle(0); DAQmxClearTask(digTaskHandle); scanEng->releaseMemory(); acqEng->releaseMemory(); }while(bContinuous && (!terminate)); /* SetCtrlVal(appState->panelHandle,PANEL_ledRunning,0); NEED IMPLEMENTATION SetCtrlVal(appState->panelHandle,PANEL_ledAcquiring,0); SetCtrlVal(appState->panelHandle,PANEL_cbx3DAcq,0); SetCtrlVal(appState->panelHandle,PANEL_cbxSave,0); */ //Disable Aom (set to 0 volts)-------------------- AomUpdate(0.0); aomCtrl->setAomOn(false); bScaleCoeffCalc = false; pDone = 0; emit acqFinished(); quit(); return; Error: //return; if( DAQmxFailed(error) ) DAQmxGetExtendedErrorInfo(errBuff,2048); //DAQmxDisconnectTerms ("/Dev1/PFI12", "/Dev1/PFI1"); if( digTaskHandle!=0 ) { // _____DAQmx Stop Code DAQmxStopTask(digTaskHandle); DAQmxClearTask(digTaskHandle); } if( scanEng->getScanTaskHandle() != 0 ) { DAQmxStopTask(scanEng->getScanTaskHandle()); DAQmxClearTask(scanEng->getScanTaskHandle()); scanEng->setScanTaskHandle(0); //SetCtrlVal(appState->panelHandle,PANEL_ledRunning,0); NEED IMPLEMENTATION //SetCtrlVal(appState->panelHandle,PANEL_ledAcquiring,0); } if( acqEng->getAcqTaskHandle() != 0 ) { DAQmxStopTask(acqEng->getAcqTaskHandle()); DAQmxClearTask(acqEng->getAcqTaskHandle()); acqEng->setAcqTaskHandle(0); } if (scanEng->getMemIsAllocated()) scanEng->releaseMemory(); if (acqEng->getMemIsAllocated()) acqEng->releaseMemory(); // if( DAQmxFailed(error) ) // QMessageBox::about(this,"DAQmx Error",errBuff); emit sendMessageForPopup("DAQmx Error",errBuff); emit acqFinished(); return; }