/***************************************************************************** - - - POLONY SEQUENCER ACQUISITION SUITE - - Church Lab - - Harvard Medical School - - - - Free software for running a Polony Sequencing automated microscope - - - - ========================================================================= - - - - - - chamcam.cpp - - - - Interface class to Hamamatsu camera (written for 9100) - - - - Written by Greg Porreca, 02-15-2006 - - - - Revised - - - - - - This software may be used, modified, and distributed freely, but this - - header may not be modified and must appear at the top of this file. - - - - - *****************************************************************************/ #include "chamcam.h" #include "dcamapi.h" #include "features.h" #include "dcamapix.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define OFFSET 0 #define BINNING 1 #define TIMEOUT 360 CHamCam::CHamCam(Reporter* rep){ r = rep; images_captured = 0; } CHamCam::~CHamCam(){;} bool CHamCam::Init(){ //get the handle of the running application hInstance = GetModuleHandle(NULL); long hCameras = 1; //initialize the memory for the FeatureVal to be used in extended func ZeroMemory((PVOID)&FeatureVal,sizeof(DCAM_PARAM_FEATURE)); FeatureVal.hdr.cbSize = sizeof(DCAM_PARAM_FEATURE); FeatureVal.hdr.id = DCAM_IDPARAM_FEATURE; //camera initialization if(dcam_init(hInstance, &hCameras, NULL)) { hDCAM = NULL;//initialize hDCAM handle to NULL //opens the camera for use and returns the camera handle if(!dcam_open(&hDCAM, 0, NULL)) return false; } else{//the camera could not be initialized r->error("camera initialization (hdcam_init()) failed", 0); return false; } //set the offset and binning mode of the camera as designated by // OFFSET and BINNING defined at the top of the file if(!SetOffsetBinning()){ r->error("could not set offset/binning in CHamCam::Init()", 0); return false; } return true;//the initialization was successful } bool CHamCam::Close() { if(!dcam_idle(hDCAM)){ r->error("cannot set camera to idle", 0); return false; } //close the camera handle and prevents future access if(!dcam_close(hDCAM)){ r->error("could not close camera handle", 0); return false; } //uninitialize the application handle if(!dcam_uninit(hInstance, NULL)){ r->error("could not uninitialize the application handle", 0); return false; } return true;//the camera was successfully closed } bool CHamCam::SetupMultiple(int num_f){ int i; if(capturing){ r->error("capturing... cannot setup right now", 0); return false; } if(setup){ r->error("already setup; cannot setup right now", 0); return false; } num_frames = num_f; //allocate memory for n images if((multipleBuffer=(void**)malloc(num_frames * sizeof(void*)))==NULL){ fprintf(stderr, "ERROR allocating array of %d void*.\n", num_frames); } for(i=0; ierror("could not set up camera for 'snap' mode", 0); return false; } else{ //setup camera to use software trigger if(!dcam_settriggermode(hDCAM, DCAM_TRIGMODE_SOFTWARE)){ r->error("could not set trigger mode to 'software'", 0); return false; } else{ //attach the user-supplied buffer allocated above if(!dcam_attachbuffer(hDCAM, multipleBuffer, num_frames * 4)){ r->error("could not attach buffer", 0); return false; } } } return true; } short unsigned int *CHamCam::GetMultiple(int index){ if(index > (images_captured - 1)){ r->error("you have not yet captured the requested image, so you can't have a pointer to it!", 0); return NULL; } return (short unsigned int*)multipleBuffer[index]; } bool CHamCam::EndMultiple(){ int i; if(!dcam_releasebuffer(hDCAM)){ r->error("could not release the buffer", 0); return false; } else{ for(i=0; ierror("could not set trigger mode to 'internal'", 0); return false; } } num_frames = 0; return true; } bool CHamCam::Trigger(){ DWORD pCode = DCAM_EVENT_VVALIDBEGIN; r->log("firing trigger",5); if(!dcam_firetrigger(hDCAM)){ r->error("could not fire trigger", 0); return false; } r->log("trigger fired",5); while(!dcam_wait(hDCAM, &pCode)){;} images_captured++; sprintf(temp_string, "num_frames: %d, images_captured: %d\n", num_frames, images_captured); r->log(temp_string, 5); return true; } bool CHamCam::DataReady(){ DWORD pCode = DCAM_EVENT_FRAMEEND; if(!dcam_wait(hDCAM, &pCode)){ return false; } return true; } bool CHamCam::QueueCapture(){ if(!dcam_capture(hDCAM)){ r->error("could not start capture cycle on software trigger", 0); return false; } images_captured = 0; return true; } bool CHamCam::SetExposure(double hExposure){ //verify the exposure is in the valid range of 100us to 10s if((hExposure < 0.0001) || (hExposure > 10)){ fprintf(stderr, "Exposure of %f is not in the valid range.\n", hExposure); exit(42); } if(!dcam_setexposuretime(hDCAM, hExposure)){ r->error("set exposure failed", 0); exit(42); } return true;//the exposure time was successfully set } bool CHamCam::SetSensitivity(float hSensitivity){ if((hSensitivity < 0) || (hSensitivity > 255)){ fprintf(stderr, "Sensitivity of %f is not in the valid range.\n", (double)hSensitivity); exit(42); } FeatureVal.featureid = DCAM_IDFEATURE_SENSITIVITY; FeatureVal.featurevalue = hSensitivity; if(!dcam_extended(hDCAM,DCAM_IDMSG_SETGETPARAM, (LPVOID)&FeatureVal,sizeof(DCAM_PARAM_FEATURE))){ r->error("set sensitivity failed", 0); return false; } return true;//the sensitivity was successfully set } bool CHamCam::SetOffsetBinning(){ if(!dcam_setbinning(hDCAM, BINNING)){ fprintf(stderr, "Could not set binning (dcam_setbinning returned false)\n"); return false; } FeatureVal.featureid = DCAM_IDFEATURE_OFFSET; FeatureVal.featurevalue = OFFSET; if(!dcam_extended(hDCAM, DCAM_IDMSG_SETGETPARAM, (LPVOID)&FeatureVal, sizeof(DCAM_PARAM_FEATURE))){ r->error("could not set offset (dcam_extended returned false)", 0); return false; } return true;//the binning and offset were successfully set }