int main(int argc, char *argv[]) { int m_sock,i,j, autoexp_gain; char autoe_filename[500]; char autoe_dirname[500]; char command_buffer[255]; // buffer for commands to be executed char image_dir[255]; sprintf(image_dir, "%s/polonator/G.007/acquisition", getenv("HOME")); sprintf(command_buffer, "mkdir -p %s", image_dir); system(command_buffer); if(argc < 2) { fprintf(stdout, "%s must be called w/ one of the following arguments:\n", argv[0]); fprintf(stdout, "\treset\t\t -- restart software on controller and home all axes\n"); fprintf(stdout, "\tunlock\t\t -- 'unlock' stage for manual movement\n"); fprintf(stdout, "\tlock\t\t -- 'lock' stage for servo movement\n"); fprintf(stdout, "\tlive\t\t -- display live darkfield image (%s live <integration in seconds> <EM gain>)\n", argv[0]); fprintf(stdout, "\tsnap\t\t -- snap image and save to disk (%s snap <color[fam, cy5, cy3, txred, spare, or none]> <integration in seconds> <EM gain>)\n", argv[0]); fprintf(stdout, "\tcolorsnap\t -- snap images in all 4 channels and save to disk (%s colorsnap <integration in seconds> <fam gain> <cy5 gain> <cy3 gain> <txred gain>)\n", argv[0]); fprintf(stdout, "\tstatus\t\t -- get motion controller status and last errors, if any\n"); fprintf(stdout, "\tcomplete-scan\t -- if scanning was interrupted, and reset the controller software gracefully to its starting state\n"); fprintf(stdout, "\tdarkfield-off\t -- turn the darkfield ring illuminator off\n"); fprintf(stdout, "\tdarkfield-on\t -- turn the darkfield ring illuminator on\n"); fprintf(stdout, "\thometheta\t -- 'lock' theta (filter cube) axis and re-home\n"); fprintf(stdout, "\tunlocktheta\t -- 'unlock' theta (filter cube) axis\n"); fprintf(stdout, "\tpower-on\t -- turn camera and fluorescence light source on\n"); fprintf(stdout, "\tpower-off\t -- turn camera and fluorescence light source off\n"); fprintf(stdout, "\tgotostagealignpos\t -- goto position used for stage alignment (%s gotostagealignpos <flowcell> <lane>)\n", argv[0]); fprintf(stdout, "\tgetfocus\t -- get current 'focus' value from Z axis (this is the offset applied to focus error signal)\n"); fprintf(stdout, "\tsetfocus\t -- set focus value for Z axis; note this DOES NOT write to non-volatile memory (%s setfocus <focus_value>)\n", argv[0]); fprintf(stdout, "\twritefocus\t -- write current focus value to non-volatile memory; should be used after correct value is found with setfocus\n"); exit(1); } /* Reset the controller software and re-home the stage */ if(strcmp(argv[1], "reset") == 0) { maestro_open(&m_sock); maestro_reset(m_sock); } else if(strcmp(argv[1], "unlock") == 0) { maestro_open(&m_sock); maestro_unlock(m_sock); } else if(strcmp(argv[1], "lock") == 0) { maestro_open(&m_sock); maestro_lock(m_sock); } else if(strcmp(argv[1], "getfocus") == 0) { maestro_open(&m_sock); return maestro_getfocus(m_sock); } else if(strcmp(argv[1], "setfocus") == 0) { maestro_open(&m_sock); maestro_setfocus(m_sock, atoi(argv[2])); } else if(strcmp(argv[1], "writefocus") == 0) { maestro_open(&m_sock); maestro_writefocus(m_sock); } /* Display a live darkfield image */ else if((strcmp(argv[1], "live") == 0) && ((argc == 4)||(argc == 5))) { maestro_open(&m_sock); maestro_darkfield_on(m_sock); maestro_setcolor(m_sock, "none"); if(argc == 4) { camera_live(argc, argv); } else { camera_live(argc, argv); } maestro_darkfield_off(m_sock); } else if((strcmp(argv[1], "live_new") == 0) && ((argc == 5)||(argc == 6))) { maestro_open(&m_sock); maestro_setcolor(m_sock, argv[4]); if(strcmp(argv[4],"none") == 0) { maestro_darkfield_on(m_sock); maestro_shutterclose(m_sock); } else { maestro_darkfield_off(m_sock); maestro_shutteropen(m_sock); } fprintf(stdout, "Live view starting"); if(argc==5) { fprintf(stdout, "Live view argc == 5"); camera_live(argc, argv); } else { fprintf(stdout, "Live view argc != 5"); camera_live(argc, argv); } fprintf(stdout, "Live view done"); if(strcmp(argv[4],"none")==0) { maestro_darkfield_off(m_sock); } else { maestro_shutterclose(m_sock); } } else if (strcmp(argv[1],"shutter_close")==0) { maestro_open(&m_sock); maestro_shutterclose(m_sock); } /* Acquire an image at the current stage position */ else if((strcmp(argv[1], "snap") == 0) && (argc == 5)) { sprintf(command_buffer, "%s/snap-image.raw", image_dir); snap(atof(argv[3]), atof(argv[4]), argv[2], command_buffer); } else if((strcmp(argv[1], "snap1") == 0) && (argc == 6)) { sprintf(command_buffer, "mkdir -p %s/autoexp_FL_images/cy3", image_dir); system(command_buffer); sprintf(command_buffer, "mkdir -p %s/autoexp_FL_images/fam", image_dir); system(command_buffer); sprintf(command_buffer, "mkdir -p %s/autoexp_FL_images/cy5", image_dir); system(command_buffer); sprintf(command_buffer, "mkdir -p %s/autoexp_FL_images/txred", image_dir); system(command_buffer); for(j = 0; j < atoi(argv[5]); j++) { maestro_open(&m_sock); maestro_gotostagealign_position(m_sock, 0, j); for(i = 0; i < 15; i++) { attempt_counter = 0; autoexp_gain = atoi(argv[4])+i*10; sprintf(autoe_filename, " ... start acquring FL image in lane %d, for %s with autoexposure gain of %d ... ",j, argv[2],autoexp_gain); p_log_simple(autoe_filename); sprintf(autoe_filename, "%s/autoexp_FL_images/%s/%d_image_%d.raw", image_dir,argv[2],j,autoexp_gain); p_log_simple(autoe_filename); wait_counter = 0; snap(atof(argv[3]), autoexp_gain, argv[2], autoe_filename); sprintf(autoe_filename, " ... acquired FL image in %d ms ...\n", wait_counter); p_log_simple(autoe_filename); while((attempt_counter < 4) && (attempt_counter > 0)) { sprintf(autoe_filename, "... ACQUIRING FAILED !!! Re-acquring FL image in lane %d, for %s with autoexposure gain of %d ...\n",atoi(argv[5]), argv[2],atoi(argv[4])); p_log_errorno(autoe_filename); snap(atof(argv[3]), atof(argv[4]), argv[2], autoe_filename); } } // end for i } // end for j } // end else if /* Acquire 4 fluorescence images */ else if((strcmp(argv[1], "colorsnap") == 0) && (argc == 7)) { sprintf(command_buffer, "%s/colorsnap-fam.raw", image_dir); snap(atof(argv[2]), atof(argv[3]), "fam", command_buffer); sprintf(command_buffer, "%s/colorsnap-cy5.raw", image_dir); snap(atof(argv[2]), atof(argv[4]), "cy5", command_buffer); sprintf(command_buffer, "%s/colorsnap-cy3.raw", image_dir); snap(atof(argv[2]), atof(argv[5]), "cy3", command_buffer); sprintf(command_buffer, "%s/colorsnap-txr.raw", image_dir); snap(atof(argv[2]), atof(argv[6]), "txred", command_buffer); } else if(strcmp(argv[1], "complete-scan") == 0) { maestro_open(&m_sock); maestro_stop(m_sock); } else if(strcmp(argv[1], "darkfield-off") == 0) { maestro_open(&m_sock); maestro_darkfield_off(m_sock); } else if(strcmp(argv[1], "darkfield-on") == 0) { maestro_open(&m_sock); maestro_darkfield_on(m_sock); } else if(strcmp(argv[1], "hometheta") == 0) { maestro_open(&m_sock); maestro_hometheta(m_sock); } else if(strcmp(argv[1], "unlocktheta") == 0) { maestro_open(&m_sock); maestro_unlocktheta(m_sock); } else if(strcmp(argv[1], "status") == 0) { maestro_open(&m_sock); maestro_getstatus(m_sock); } else if(strcmp(argv[1], "power-on") == 0) { network_iboot_on(&m_sock); } else if(strcmp(argv[1], "power-off") == 0) { network_iboot_off(&m_sock); } else if(strcmp(argv[1], "gotostagealignpos") == 0) { maestro_open(&m_sock); maestro_gotostagealign_position(m_sock, atoi(argv[2]), atoi(argv[3])); } else { main(1, argv); } } // end function
void stagealign(int fcnum, int lane_num, int initialize) { short unsigned int *testimage; short unsigned int *baseimage; FILE *baseimgfp; FILE *offsetfp; /* used to dump score matrix to file when debugging */ FILE *score_matrixfp; /* Maestro declarations */ int m_sock; /* socket for the Maestro controller */ char config_value[255]; char logfilename[255]; char offsetfilename[255]; char stagealign_baseimgfilename[255]; char acqcfgpath[255]; /* Used to send commands and receive responses from Maestro */ char command[255]; char response[255]; int response_length; /* Image acquisition settings, populated from config file */ int stagealign_integration_inmsec; int stagealign_gain; int stagealign_well; int stagealign_wells_per_fc; /* Values used for conversion between pixels and stage units */ int stagealign_optical_mag; int ccd_pixel_size; double pixelsize_at_stage; /* size of a pixel at the stage in microns */ /* Hold offsets found by alignment in pixels and stageunits */ int pixel_offset_x, pixel_offset_y; double stageunit_offset_x, stageunit_offset_y; int lane_index; /* Holds previous offsets from controller in case the alignment doesn't work */ int curr_offset_x, curr_offset_y; /* Holds encoder resolutions from controller, used for calculating distance of move */ double encoder_res_X, encoder_res_Y; /* 'score' of best alignment */ int score; /* Largest pixel offset allowable _after_ the adjustment has been made */ /* if there is still a shift larger than this, conclude something is wrong */ /* and go back to the previous offset */ int successful_move_threshold = 150; /*RCT was = 12*/ int i; /* in debugging mode, dump internal data to files */ #ifdef DEBUG_STAGEALIGN FILE *imgfp; sprintf(command, "%s/stagealign-image%d_%d.raw", output_directory, fcnum, lane_num); imgfp = fopen(command, "w"); sprintf(command, "%s/stagealign-scorematrix%d_%d", output_directory, fcnum, lane_num); score_matrixfp = fopen(command, "w"); #endif p_log_simple("awesome2\n"); /* Open config file */ strcpy(acqcfgpath, getenv("POLONATOR_PATH")); strcat(acqcfgpath, "/config_files/polonator-acq.cfg"); config_open(acqcfgpath); p_log_simple("awesome1\n"); /* Initialize variables */ if(!config_getvalue("stagealign_logfilename", config_value)){ fprintf(stderr, "ERROR:\tPolonator-stagealign: config_getval(key logfilename) returned no value\n"); exit(0); } p_log_simple("awesome0\n"); strcpy(logfilename, log_dir); strcat(logfilename, "/"); strcat(logfilename, config_value); sprintf(command, "%d", fcnum); strcat(logfilename, command); strcat(logfilename, ".log"); p_log_simple(logfilename); start_logger(logfilename, 1); strcpy(offsetfilename, log_dir); strcat(offsetfilename, "/"); strcat(offsetfilename, config_value); strcat(offsetfilename, command); strcat(offsetfilename, ".offsetlog"); fprintf(stdout, offsetfilename); fflush(stdout); /* if this is being run in 'initialize mode' -- the first scan of a run -- overwrite the offset logfile */ p_log_simple("awesome66\n"); if(initialize){ offsetfp = fopen(offsetfilename, "w"); } else{ offsetfp = fopen(offsetfilename, "a"); } p_log_simple("awesome00\n"); if(!config_getvalue("stagealign_baseimgfilename", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_baseimgfilename) returned no value"); exit(0); } sprintf(stagealign_baseimgfilename, "%s/%s%s_%d.raw", output_directory, config_value, command, lane_num); p_log_simple("awesome01\n"); if(!config_getvalue("stagealign_integration_inmsec", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_integration_inmsec) returned no value"); exit(0); } stagealign_integration_inmsec = atoi(config_value); p_log_simple("awesome02\n"); if(!config_getvalue("stagealign_gain", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_gain) returned no value"); exit(0); } stagealign_gain = atoi(config_value); p_log_simple("awesome03\n"); if(!config_getvalue("stagealign_optical_mag", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_optical_mag) returned no value"); exit(0); } stagealign_optical_mag = atoi(config_value); p_log_simple("awesome04\n"); if(!config_getvalue("stagealign_ccd_pixel_size", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_ccd_pixel_size) returned no value"); exit(0); } ccd_pixel_size = atoi(config_value); p_log_simple("awesome05\n"); if(!config_getvalue("stagealign_wells_per_fc", config_value)){ p_log("ERROR:\tPolonator-stagealign: config_getval(key stagealign_wells_per_fc) returned no value"); exit(0); } stagealign_wells_per_fc = atoi(config_value); config_close(); p_log_simple("awesome06\n"); stagealign_well = lane_num; lane_index = (fcnum * stagealign_wells_per_fc) + stagealign_well; baseimage = (short unsigned int*)malloc(1000000 * sizeof(short unsigned int)); /*-------------------------------------------------------------------------- // // MAESTRO SETUP /*/ p_log_simple("STATUS:\tPolonator-stagealign: Opening connection to Maestro..."); maestro_open(&m_sock); /* //-------------------------------------------------------------------------- */ /*-------------------------------------------------------------------------- // // CAMERA SETUP /*/ p_log_simple("STATUS:\tPolonator-stagealign: Opening camera handle..."); py_cameraInit(0); /* use non-TDI config file */ py_set_gain(stagealign_gain); py_setupSnap(); /* setup capture software to wait for images from camera */ /* //-------------------------------------------------------------------------- */ /*p_log("STATUS:\tPolonator-stagealign: Darkfield illuminator on..."); rolony*/ /*maestro_darkfield_on(m_sock); p_log("STATUS:\tPolonator-stagealign: Select darkfield filter block..."); rolony*/ maestro_setcolor(m_sock, "cy5"); /* IF INITIALIZING, RESET OFFSETS */ if(initialize){ p_log_simple("INITIALIZING STAGEALIGN"); sprintf(command, "PolonatorScan.OFFSET_X[%d]=0\n\r", lane_index); p_log_simple(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log_simple(response); sprintf(command, "PolonatorScan.OFFSET_Y[%d]=0\n\r", lane_index); p_log_simple(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log_simple(response); } /* GET OFFSETS IN CASE ALIGNMENT FAILS */ else{ p_log_simple("Storing current offsets..."); sprintf(command, "PolonatorScan.OFFSET_X[%d]\n\r", lane_index); p_log_simple(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log_simple(response); curr_offset_x = atoi(response); sprintf(command, "PolonatorScan.OFFSET_Y[%d]\n\r", lane_index); p_log_simple(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log_simple(response); curr_offset_y = atoi(response); } /* MOVE STAGE TO ORIGIN */ maestro_gotostagealign_position(m_sock, fcnum, lane_num); p_log_simple("awesome fool00\n"); /* ACQUIRE IMAGE */ p_log("STATUS:\tPolonator-stagealign: Acquire image..."); maestro_snap(m_sock, stagealign_integration_inmsec, 1); /*rolony*/ while(!py_snapReceived()){;} testimage = py_getSnapImage(); /* IF INITIALIZING, RE-WRITE THE BASE IMAGE; THE OFFSET FOUND SHOULD BE ZERO */ p_log_simple(stagealign_baseimgfilename); if(initialize){ baseimgfp = fopen(stagealign_baseimgfilename, "w"); fwrite(testimage, 1000000, sizeof(short unsigned int), baseimgfp); fclose(baseimgfp); } p_log_simple("awesome fool01\n"); #ifdef DEBUG_STAGEALIGN fwrite(testimage, 1000000, sizeof(short unsigned int), imgfp); #endif /* LOAD BASE IMAGE */ p_log("STATUS:\tPolonator-stagealign: Load base image and determine offset..."); baseimgfp = fopen(stagealign_baseimgfilename, "r"); fread(baseimage, 1000000, sizeof(short unsigned int), baseimgfp); fclose(baseimgfp); p_log("STATUS:\tPolonator-stagealign: Load base image and determine offset2..."); /* DETERMINE OFFSETS */ register_image(baseimage, testimage, &pixel_offset_x, &pixel_offset_y, &score, score_matrixfp); sprintf(log_string, "STATUS:\tPolonator-stagealign: Found pixel offsets X:%d, Y:%d, score:%d", pixel_offset_x, pixel_offset_y, score); p_log(log_string); /* LOAD ENCODER RESOLUTIONS FOR CONVERSION BELOW; THESE ARE STORED ON */ /* THE CONTROLLER AS COUNTS PER MILLIMETER */ p_log("Retrieving encoder resolutions..."); sprintf(command, "PolonatorScan.cENCODER_X_RESOLUTION\n\r"); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); encoder_res_X = atof(response); sprintf(command, "PolonatorScan.cENCODER_Y_RESOLUTION\n\r"); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); encoder_res_Y = atof(response); /* CONVERT FROM PIXELS TO STAGE UNITS */ /* CALCULATE PIXEL SIZE IN MILLIMTERS AT THE STAGE BASED */ /* ON THE MAGNIFICATION AND THE CCD PIXEL SIZE */ pixelsize_at_stage = ((double)ccd_pixel_size / (double)stagealign_optical_mag) / 1000; stageunit_offset_x = (double)pixel_offset_x * pixelsize_at_stage * encoder_res_X * -1; stageunit_offset_y = (double)pixel_offset_y * pixelsize_at_stage * encoder_res_Y * -1; /* SET NEW OFFSETS ON CONTROLLER USING VALUES */ /* CALCULATED ABOVE */ sprintf(command, "PolonatorScan.OFFSET_X[%d]\n\r", lane_index); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); fprintf(offsetfp, "%d\t%d\t", fcnum, stagealign_well); fprintf(offsetfp, "%d\t", atoi(response)); sprintf(command, "PolonatorScan.OFFSET_Y[%d]\n\r", lane_index); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); fprintf(offsetfp, "%d\t", atoi(response)); fprintf(offsetfp, "%d\t%d\t%d\t%d\t", (int)stageunit_offset_x, (int)stageunit_offset_y, pixel_offset_x, pixel_offset_y); /* ISSUE COMMANDS TO ADJUST STAGE COORDS */ p_log("STATUS:\tPolonator-stagealign: Set offset variables on Maestro..."); sprintf(command, "PolonatorScan.OFFSET_X[%d]=PolonatorScan.OFFSET_X[%d]+%d\n\r", lane_index, lane_index, (int)stageunit_offset_x); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); sprintf(command, "PolonatorScan.OFFSET_Y[%d]=PolonatorScan.OFFSET_Y[%d]+%d\n\r", lane_index, lane_index, (int)stageunit_offset_y); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); /* MOVE, THEN ACQUIRE ANOTHER IMAGE TO VERIFY OFFSET WORKED */ /* maestro_gotostagealign_position(m_sock, fcnum, lane_num); maestro_snap(m_sock, stagealign_integration_inmsec, 0); while(!py_snapReceived()){;} testimage = py_getSnapImage(); */ #ifdef DEBUG_STAGEALIGN fwrite(testimage, 1000000, sizeof(short unsigned int), imgfp); fclose(imgfp); #endif /* DETERMINE OFFSET TO CONFIRM */ /* p_log("STATUS:\tPolonator-stagealign: Re-compute alignment to verify move..."); register_image(baseimage, testimage, &pixel_offset_x, &pixel_offset_y, &score, score_matrixfp); sprintf(log_string, "STATUS:\tPolonator-stagealign: Found pixel offsets X:%d, Y:%d, score:%d", pixel_offset_x, pixel_offset_y, score); p_log(log_string); fprintf(offsetfp, "%d\t%d", pixel_offset_x, pixel_offset_y); */ /* DID THE MOVE WORK? */ if(((abs(pixel_offset_x)>successful_move_threshold) || (abs(pixel_offset_y)>successful_move_threshold)) && (!initialize)) { sprintf(log_string, "ERROR:\tPolonator-stagealign: one or more offsets are greater that the %d-pixel maximum; X:%d, Y:%d", successful_move_threshold, pixel_offset_x, pixel_offset_y); p_log(log_string); fprintf(offsetfp, "*"); /* mark current line in offsetlog, since offsets found will not be the offsets stored on the controller */ sprintf(log_string, "Restoring previous offsets X:%d, Y:%d", curr_offset_x, curr_offset_y); sprintf(command, "PolonatorScan.OFFSET_X[%d]=%d\n\r", lane_index, curr_offset_x); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); sprintf(command, "PolonatorScan.OFFSET_Y[%d]=%d\n\r", lane_index, curr_offset_y); p_log(command); send(m_sock, command, strlen(command), 0); maestro_readresponse(m_sock, response, &response_length); p_log(response); } /* EXIT */ #ifdef DEBUG_STAGEALIGN fclose(score_matrixfp); #endif fprintf(offsetfp, "\n"); fclose(offsetfp); /*maestro_darkfield_off(m_sock); rolony*/ py_cameraClose(); free(baseimage); close_logger(); p_log_simple("awesome fool02\n"); }
void snap(float exposure, float gain, char *color, char *filename) { int m_sock; short unsigned int *image; int imgmean; int shutterflag; FILE *outfile; wait_counter = 0; // open hardware and file camera_init(); // use non-TDI config file setGain(gain); maestro_open(&m_sock); outfile = fopen(filename, "w"); // configure hardware maestro_setcolor(m_sock, color); //maestro_darkfield_off(m_sock); //setGain(gain);moved to line 174 // determine whether or not to use the shutter if(!strcmp(color, "none")) { shutterflag = 0; maestro_darkfield_on(m_sock); } else { shutterflag = 1; maestro_darkfield_off(m_sock); } // setup the software to receive an image from the camera setupSnap(); // snap the image maestro_snap(m_sock, (int)(exposure * 1000.0), shutterflag); // wait for image to be received by framegrabber while(!snapReceived()) { wait_counter++; usleep(1000); if(wait_counter > 20000) { attempt_counter++; network_iboot_off(&m_sock); sleep(1); network_iboot_on(&m_sock); sleep(1); wait_counter = 0; } } // get pointer to image image = getSnapImage(); // calculate mean for informational purposes, then write image to file imgmean = imagemean(image); fprintf(stdout, "Image mean: %d\n", imgmean); fwrite(image, sizeof(short unsigned int), 1000000, outfile); fprintf(stdout, "finish outputing image"); // close hardware and file if(!strcmp(color, "none")) maestro_darkfield_off(m_sock); fclose(outfile); fprintf(stdout, "closing camera"); camera_close(); } // end function