def unscramble(num_im, num_slices, input_file_name, output_file_name): interlaced_image_raw = tif_to_array(input_file_name).astype(np.float64) ##check to make sure I am divisible by num_im num_columns = interlaced_image_raw.shape[-1] extra_pixels = num_columns % num_im if extra_pixels == 0: interlaced_image = interlaced_image_raw else: interlaced_image = interlaced_image_raw[:, :, :num_columns-extra_pixels] zstacks = num_im * num_slices yrows = interlaced_image.shape[-2] xcolumns = (interlaced_image.shape[-1]/num_im) sorted_image_stack = np.zeros((zstacks, yrows, xcolumns), dtype= interlaced_image.dtype) for j in range(num_slices): ##l2r for i in range(num_im): sorted_image_stack[(j*num_im) + i, :, :] = interlaced_image[j, :, i::num_im] ##r2l for i in range(num_im): sorted_image_stack[(j*num_im) + i, :, :] = interlaced_image[j, :, i::num_im] array_to_tif(sorted_image_stack.astype(np.float32), output_file_name) print "Image 1:", sorted_image_stack.shape, sorted_image_stack.dtype
def image_filename_to_array( image_filename, shape=None, dtype=None, verbose=True, config=None, master=None): """Load tif (.tif, .tiff extension) and raw binary files (.dat, .raw extension). If raw binary, 'dtype' and 'shape' must be specified.""" if verbose: print "Loading %s..."%(os.path.split(image_filename)[1]) extension = os.path.splitext(image_filename)[1] if extension in ('.tif', '.tiff'): a, info = tif_to_array(image_filename, return_info=True) info = dict([x.split('=') for x in info['description'].split('\n') if len(x.split('=')) > 1]) if verbose and int(info.get('channels', 1)) > 1: print "Image data seems to be an ImageJ hyperstack", print " with multiple colors." channels = int(info['channels']) else: channels = 1 return a, channels elif extension in ('.raw', '.dat'): if (shape is None) or (dtype is None): info = get_image_info( image_filename, config=config, master=master) if info == 'cancelled': return 'cancelled', None xy_shape, dtype_name = info config.set('File', 'last_leftright_shape', repr(xy_shape[1])) config.set('File', 'last_updown_shape', repr(xy_shape[0])) config.set('File', 'last_dtype', dtype_name) save_config(config) dtype = { 'uint8': numpy.uint8, 'uint16': numpy.uint16, 'uint32': numpy.uint32, 'float32': numpy.float32, 'float64': numpy.float64, }[dtype_name] else: xy_shape = shape[1:] data = numpy.fromfile(image_filename, dtype=dtype) try: data = data.reshape( (data.size // (xy_shape[0] * xy_shape[1]),) + xy_shape) except ValueError: print xy_shape, dtype raise UserWarning("The given shape and datatype do not match" + " the size of %s"%( os.path.split(image_filename)[1])) return data, 1 #Multi-channel raw is probably to be avoided else: raise UserWarning("Extension '%s' not recognized.\n"%(extension) + "File extension must be one of:\n" " ('.tif', '.tiff', '.raw', '.dat').")
def initialize_volume(self): volume_voltages = np.zeros((30000, self.daq.num_mutable_channels), dtype=np.float64) ##objective starts where it was objective_voltage = self.daq.default_voltages[-1, n2c['objective']] volume_voltages[:, n2c['objective']] = objective_voltage ##objective does loaded scan loaded_signal = tif_to_array( filename='input_voltage_objective_01.tif').astype( np.float64).ravel() loaded_signal += objective_voltage volume_voltages[:22500, n2c['objective']] = loaded_signal[:] print "min", oh_snap_voltages[:, n2c['objective']].min() print "max", oh_snap_voltages[:, n2c['objective']].max() ##excitation galvo starts where it was galvo_voltage = self.daq.default_voltages[-1, n2c['excitation_scan']] volume_voltages[:, n2c['excitation_scan']] = galvo_voltage ##excitation galvo scans illumination galvo_voltage[5000:10000] = np.linspace( galvo_voltage, galvo_voltage + 0.2, 5000) galvo_voltage[10000:12500] = galvo_voltage + 0.2 galvo_voltage[12500:17500] = np.linspace( galvo_voltage + 0.2, galvo_voltage, 5000) ##murrcle stays at what it was murrcle_voltage = self.daq.default_voltages[-1, n2c['emission_scan']] oh_snap_voltages[:, n2c['emission_scan']] = murrcle_voltage #Camera triggers at the start of a write oh_snap_voltages[:self.daq.write_length//4, n2c['camera']] = 3 #AOTF fires on one perpendicular facet start_point_laser = (#Integer num of writes plus a perp facet time self.daq.perpendicular_facet_times[6] + self.illumination_offset+ self.daq.write_length * int(roll_time * 1.0 / self.daq.write_length)) oh_snap_voltages[start_point_laser:start_point_laser+self.illumination_length, n2c['488']] = 10 oh_snap_voltages[start_point_laser:start_point_laser+self.illumination_length, n2c['blanking']] = 10 ## oh_snap_voltages[start_point_laser, n2c['blanking']] = 10 time.sleep(1) """ let's test the objective impulse response """ ## marker = start_point_laser ## scan = np.linspace(5, 6, 5000) ## oh_snap_voltages[marker:(marker+5000), n2c['objective']] = scan ## marker += 5000 ## oh_snap_voltages[marker:( ## marker+2500), n2c['objective']] = 6 ## marker += 2500 ## oh_snap_voltages[marker:( ## marker+5000), n2c['objective']] = np.linspace(6,5,5000) ## marker += 5000 ## loaded_signal = tif_to_array( ## filename='input_voltage_objective_00.tif').astype( ## np.float64).ravel() ## loaded_signal += objective_voltage ## oh_snap_voltages[:22500, n2c['objective']] = loaded_signal[:] ## print "min", oh_snap_voltages[:, n2c['objective']].min() ## print "max", oh_snap_voltages[:, n2c['objective']].max() ## ## loaded_desired_signal = tif_to_array( ## filename='desired_result_objective.tif').astype( ## np.float64).ravel() ## loaded_desired_signal += objective_voltage ## loaded_desired_signal[0] += 1 ## oh_snap_voltages[:, n2c['561']] = objective_voltage ## oh_snap_voltages[:22500, n2c['561']] = loaded_desired_signal[:] print oh_snap_voltages.shape self.daq.send_voltage(oh_snap_voltages, 'snap') return None
def initialize_characterize(self): """ Create the murrrcle signal up here. All we care about is how many DAQ points long it is. """ ## impulse_strength = 1 ## num_periods = 4 ## daq_timepoints_per_period = 1500 ## amplitude_volts = 0.1 ## murrcle_signal = np.sin(np.linspace( ## 0, 2*np.pi*num_periods, num_periods * daq_timepoints_per_period)) ## murrcle_signal[:daq_timepoints_per_period] = 0 ## murrcle_signal[-daq_timepoints_per_period:] = 0 murrcle_signal = np.zeros(20000, dtype=np.float64) default_murrcle = self.daq.default_voltages[-1, n2c['emission_scan']] murrcle_signal[:] = default_murrcle ## murrcle_signal[1000:1152] = 0.05 ## murrcle_signal[1152:-1000] = 0.1 ## murrcle_signal[200:204] = default_murrcle + impulse_strength """ Read in an arbitrary signal from a tif file """ loaded_signal = tif_to_array( filename='input_voltage_to_mirror_05.tif').astype(np.float64) ## loaded_signal += default_murrcle ## loaded_signal *= 1.75 ## ## loaded_signal[loaded_signal < 0] *= 0.45 ## ## print "Pre Loaded signal min, max:", ## print loaded_signal.min(), loaded_signal.max() ## print "Loaded signal min, max:", print loaded_signal.min(), loaded_signal.max() print """ Put this optimzed waveform into the larger array """ murrcle_signal[:loaded_signal.size] = loaded_signal[:, 0, 0] print "Loaded signal size", loaded_signal.size ## """ ## Smoothly drop the voltage to default; hopefully this reduces ringing. ## """ ## murrcle_signal[loaded_signal.size:2*(loaded_signal.size) ## ] = np.linspace( ## loaded_signal[-1, 0, 0], ## default_murrcle, ## loaded_signal.size) ## print "last value for signal" , loaded_signal[-1, 0 , 0] ## print murrcle_signal[loaded_signal.size * 1.5] #Remove this soon ## self.characterization_points = murrcle_signal.size delay_points = max(#Figure out the limiting factor murrcle_signal.size, 1e-6 * self.get_camera_rolling_time_microseconds() * self.daq.rate) start_point_laser = (#Integer num of writes plus a perp facet time self.daq.perpendicular_facet_times[0] + self.daq.write_length * int(np.ceil(delay_points * 1.0 / self.daq.write_length))) assert (self.exposure_time_microseconds * 1e6 >= start_point_laser * 1.0 / self.daq.rate) voltage = np.zeros(((start_point_laser + murrcle_signal.shape[0]), self.daq.num_mutable_channels), dtype=np.float64) """ Trigger the camera """ voltage[:self.daq.write_length//4, n2c['camera']] = 3 """ Trigger the laser """ voltage[start_point_laser, n2c['488']] = 10 voltage[start_point_laser, n2c['blanking']] = 10 """ Wiggle the murrrrcle """ print "murrcle_Signal[0]", murrcle_signal[0] print "murrcle_Signal[-1]", murrcle_signal[-1] print "default murrcle", default_murrcle ## assert murrcle_signal[0] == default_murrcle assert murrcle_signal[-1] == default_murrcle voltage[:, n2c['emission_scan']] = default_murrcle voltage[-murrcle_signal.size:, n2c['emission_scan']] = murrcle_signal print "Impulse starts at DAQ pixel:", print voltage.size - murrcle_signal.size + 250 """ Objective stays at what it was """ objective_voltage = self.daq.default_voltages[-1, n2c['objective']] voltage[:, n2c['objective']] = objective_voltage """ Excitation Galvo stays at what it was """ galvo_voltage = self.daq.default_voltages[-1, n2c['excitation_scan']] voltage[:, n2c['excitation_scan']] = galvo_voltage self.daq.send_voltage(voltage, 'characterize') return None
for s, sig in enumerate(sigmas): density += gaussian_filter(multiview_data[s, :, :], sigma=sig) density *= 1.0 / len(sigmas) return density def multiview_data_to_visualization(multiview_data, outfile=None): if outfile is not None: array_to_tif(multiview_data.astype(np.float32), outfile) return multiview_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('resolution_target.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """
for m in range(msim_data.shape[2]): for n in range(msim_data.shape[3]): interpolation.shift( input=msim_data[:, :, m, n], shift=(0.5*(m - 0.5*msim_data.shape[2]), 0.5*(n - 0.5*msim_data.shape[3])), output=shifted_msim_data[:, :, m, n], order=3) shifted_msim_data[shifted_msim_data < 0] = 0 #Interpolation can produce zeros return shifted_msim_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('ladder_complete.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 20#40 blur_size = 2#10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """
for m in range(msim_data.shape[2]): for n in range(msim_data.shape[3]): interpolation.shift( input=msim_data[:, :, m, n], shift=(0.5*(m - 0.5*msim_data.shape[2]), 0.5*(n - 0.5*msim_data.shape[3])), output=shifted_msim_data[:, :, m, n], order=3) shifted_msim_data[shifted_msim_data < 0] = 0 #Interpolation can produce zeros return shifted_msim_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('lena_gray.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """
def result_optimization_units_to_mirror_units(er): return (er * 155.0) * scale + shift - 46.0 # Watch out for DC drift here def result_mirror_units_to_optimization_units(er): return (((er - shift + 46.0) * 1.0 / scale)) / 155.0 assert ( result_mirror_units_to_optimization_units(result_optimization_units_to_mirror_units(1)) == 1.0 ) # Careful! Floats! if __name__ == "__main__": input_voltage = simple_tif.tif_to_array("input_voltage.tif").astype(np.float64) expected_result = simple_tif.tif_to_array("expected_result.tif").astype(np.float64) simple_tif.array_to_tif( voltage_optimization_units_to_mirror_units(input_voltage).astype(np.float32), "input_voltage_to_mirror.tif" ) simple_tif.array_to_tif( result_optimization_units_to_mirror_units(expected_result).astype(np.float32), "expected_result_from_chip.tif" ) plt.figure() plt.subplot(2, 1, 1) plt.plot(voltage_optimization_units_to_mirror_units(input_voltage).ravel(), label="Voltage to mirror") plt.grid("on") plt.legend() plt.subplot(2, 1, 2)
input_voltage_cursor += len_ramp ##plt.figure() ##plt.plot(input_voltage_sample) ##plt.plot(time, desired_result_sample, '.') ##plt.plot(time, H(input_voltage_sample), '.') ##plt.plot(input_voltage_camera) ##plt.plot(time, desired_result_camera, '.') ##plt.plot(time, H(input_voltage_camera), '.') ##plt.show() naive_input_voltage_sample = input_voltage_sample.copy() naive_input_voltage_camera = input_voltage_camera.copy() print "Loading 'input_voltage_sample.tif' and 'input_voltage_camera.tif'..." try: input_voltage_sample = simple_tif.tif_to_array('input_voltage_sample.tif' ).ravel().astype(np.float64) input_voltage_camera = simple_tif.tif_to_array('input_voltage_camera.tif' ).ravel().astype(np.float64) print "Initial guess loaded" except IOError: print "Loading failed. Using naive input voltages as initial guess." iterations = 1000000 regularization = 0.1 plt.close('all') plt.figure() for i in range(iterations): print 'Iteration', i expected_result_sample = H(input_voltage_sample) expected_result_camera = H(input_voltage_camera)
if not os.path.exists(previous_result_filename): raise UserWarning("Result data not found") break print iteration print "Previous:" print ' ', previous_input_voltage_filename print ' ', previous_result_filename print 'Creating:' print ' ', new_input_voltage_filename """ Load everything in optimization units """ previous_input_voltage = simple_tif.tif_to_array( previous_input_voltage_filename).ravel().astype(np.float64) previous_input_voltage = ( convert_units.voltage_mirror_units_to_optimization_units( previous_input_voltage)) if iteration == 0: """ The pre-optimizer isn't allowed to write voltages during the linker; this optimizer is. Pad with zeros. """ previous_input_voltage = np.concatenate((previous_input_voltage, np.zeros(len_linker))) desired_result = simple_tif.tif_to_array('expected_result.tif' ).ravel().astype(np.float64) desired_result = np.concatenate((desired_result, np.zeros(len_deadzone, dtype=np.float64))) assert desired_result.size == previous_input_voltage.size + len_deadzone
def initialize_characterize(self): """ Create the murrrcle signal up here. All we care about is how many DAQ points long it is. """ ## impulse_strength = 1 ## num_periods = 4 ## daq_timepoints_per_period = 1500 ## amplitude_volts = 0.1 ## murrcle_signal = np.sin(np.linspace( ## 0, 2*np.pi*num_periods, num_periods * daq_timepoints_per_period)) ## murrcle_signal[:daq_timepoints_per_period] = 0 ## murrcle_signal[-daq_timepoints_per_period:] = 0 murrcle_signal = np.zeros(20000, dtype=np.float64) default_murrcle = self.daq.default_voltages[-1, n2c['emission_scan']] murrcle_signal[:] = default_murrcle ## murrcle_signal[1000:1152] = 0.05 ## murrcle_signal[1152:-1000] = 0.1 ## murrcle_signal[200:204] = default_murrcle + impulse_strength """ Read in an arbitrary signal from a tif file """ loaded_signal = tif_to_array( filename='input_voltage_to_mirror_05.tif').astype(np.float64) ## loaded_signal += default_murrcle ## loaded_signal *= 1.75 ## ## loaded_signal[loaded_signal < 0] *= 0.45 ## ## print "Pre Loaded signal min, max:", ## print loaded_signal.min(), loaded_signal.max() ## print "Loaded signal min, max:", print loaded_signal.min(), loaded_signal.max() print """ Put this optimzed waveform into the larger array """ murrcle_signal[:loaded_signal.size] = loaded_signal[:, 0, 0] print "Loaded signal size", loaded_signal.size ## """ ## Smoothly drop the voltage to default; hopefully this reduces ringing. ## """ ## murrcle_signal[loaded_signal.size:2*(loaded_signal.size) ## ] = np.linspace( ## loaded_signal[-1, 0, 0], ## default_murrcle, ## loaded_signal.size) ## print "last value for signal" , loaded_signal[-1, 0 , 0] ## print murrcle_signal[loaded_signal.size * 1.5] #Remove this soon ## self.characterization_points = murrcle_signal.size delay_points = max( #Figure out the limiting factor murrcle_signal.size, 1e-6 * self.get_camera_rolling_time_microseconds() * self.daq.rate) start_point_laser = ( #Integer num of writes plus a perp facet time self.daq.perpendicular_facet_times[0] + self.daq.write_length * int(np.ceil(delay_points * 1.0 / self.daq.write_length))) assert (self.exposure_time_microseconds * 1e6 >= start_point_laser * 1.0 / self.daq.rate) voltage = np.zeros(((start_point_laser + murrcle_signal.shape[0]), self.daq.num_mutable_channels), dtype=np.float64) """ Trigger the camera """ voltage[:self.daq.write_length // 4, n2c['camera']] = 3 """ Trigger the laser """ voltage[start_point_laser, n2c['488']] = 10 voltage[start_point_laser, n2c['blanking']] = 10 """ Wiggle the murrrrcle """ print "murrcle_Signal[0]", murrcle_signal[0] print "murrcle_Signal[-1]", murrcle_signal[-1] print "default murrcle", default_murrcle ## assert murrcle_signal[0] == default_murrcle assert murrcle_signal[-1] == default_murrcle voltage[:, n2c['emission_scan']] = default_murrcle voltage[-murrcle_signal.size:, n2c['emission_scan']] = murrcle_signal print "Impulse starts at DAQ pixel:", print voltage.size - murrcle_signal.size + 250 """ Objective stays at what it was """ objective_voltage = self.daq.default_voltages[-1, n2c['objective']] voltage[:, n2c['objective']] = objective_voltage """ Excitation Galvo stays at what it was """ galvo_voltage = self.daq.default_voltages[-1, n2c['excitation_scan']] voltage[:, n2c['excitation_scan']] = galvo_voltage self.daq.send_voltage(voltage, 'characterize') return None