예제 #1
0
def pipeline_run_sim(path):
    startTime = time.time()
    if os.path.exists(path) == True:
        location = path + '/data'
        mask.MASK(path)
        ref_image(location)
        align_astroalign.align2(location)
        print("-> Combining images using swarp method...")
        psf.PSF(path)
        combine_swarp.swarp(location)
        psf.PSF(path)
        print("\n-> Subtracting images using AIS method...")
        subtract_ais.isis_sub(path)
        optimize.perform_optimization(path)
        print("-> Running SExtractor on residuals...")
        extract.EXTRACT(path, method='indiv')
        MR.MR_swarp(path)
        extract.EXTRACT(path, method='MR')
        endTime = time.time()
        print("-> Finished!\n-> Total runtime: %.2f seconds\n" %
              (endTime - startTime))
    else:
        print(
            "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n"
        )
        sys.exit()
def generate_psf(x,
                 y,
                 cmap='hot',
                 savebin=False,
                 savetif=True,
                 savevol=False,
                 plot=True,
                 **kwargs):
    """Calculate, save, and plot various point spread functions."""

    args = {
        'shape': (x, y),  # number of samples in z and r direction
        'dims': (10.0, 10.0),  # size in z and r direction in micrometers
        'ex_wavelen': 488.0,  # excitation wavelength in nanometers
        'em_wavelen': 520.0,  # emission wavelength in nanometers
        'num_aperture': 1.2,
        'refr_index': 1.333,
        'magnification': 1.0,
        'pinhole_radius': 0.05,  # in micrometers
        'pinhole_shape': 'round',
    }
    args.update(kwargs)

    obsvol = psf.PSF(psf.ISOTROPIC | psf.CONFOCAL, **args)
    expsf = obsvol.expsf
    empsf = obsvol.empsf
    gauss = gauss2 = psf.PSF(psf.GAUSSIAN | psf.EXCITATION, **args)

    print(obsvol)
    return (obsvol.data)
예제 #3
0
def PIPELINE(path):
    '''The **OASIS Pipeline**. Runs all **OASIS** functions in succession.
    
    :param str path: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets.
    :returns: All-in-one difference imaging pipeline. Raw science images are placed in the **data** directory, and residual images and source catalogs are outputted into the **residuals** and **sources** directories, respectively.
    
    '''
    paths = (path.replace(' ', '')).split(',')
    del path
    for path in paths:
        startTime = time.time()
        if os.path.exists(path) == True:
            initialize.create(path)
            location = path + '/data'
            mask.MASK(path)
            sat = check_saturation.check_saturate(location)
            if sat == 0:
                ref_image(location)
                align_astroalign.align2(location)
            else:
                check = input(
                    "-> Saturated images found\n-> Move saturated images to OASIS archive? (y/n): "
                )
                if check == 'y':
                    check_saturation.move_arch(sat)
                    ref_image(location)
                    align_astroalign.align2(location)
                elif check == 'n':
                    ref_image(location)
                    align_astroalign.align2(location)
                else:
                    print("-> Error: Unknown input")
                    sys.exit()
            print("-> Combining images using swarp method...")
            psf.PSF(path)
            combine_swarp.swarp(location)
            psf.PSF(path)
            print("\n-> Subtracting images using AIS method...")
            subtract_ais.isis_sub(path)
            optimize.perform_optimization(path)
            print("-> Running SExtractor on residuals...")
            extract.EXTRACT(path, method='indiv')
            MR.MR(path)
            extract.EXTRACT(path, method='MR')
            endTime = time.time()
            print("-> Finished!\n-> Total runtime: %.2f seconds\n" %
                  (endTime - startTime))
        else:
            print(
                "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n"
            )
            sys.exit()
예제 #4
0
def psf_sample(n_z_slices=64, depth_in_microns=0.4, r_in_microns=28.0):
    assert n_z_slices > 1  # psf.PSF fails if shape == 1
    args = dict(
        shape=(n_z_slices, 128),  # number of samples in z and r direction
        dims=(
            depth_in_microns,
            r_in_microns,
        ),  # size in z and r direction in micrometers
        ex_wavelen=640.0,  # excitation wavelength in nanometers
        em_wavelen=665.0,  # emission wavelength in nanometers
        num_aperture=1.49,
        refr_index=1.51,
        magnification=1.0,
        pinhole_radius=1.50,  # in micrometers
        pinhole_shape="round",
    )
    obsvol = psf.PSF(psf.ISOTROPIC | psf.CONFOCAL, **args)
    width = 8
    width2 = width // 2
    psfs = []
    for zi in range(n_z_slices):
        im = psf.mirror_symmetry(obsvol.empsf.slice(zi))
        mea = im.shape[0] + 1
        mea2 = mea // 2
        im = im[mea2 - width2:mea2 + width2 - 1,
                mea2 - width2:mea2 + width2 - 1]
        im = im / np.sum(im)
        psfs += [im]
    return np.array(psfs)
예제 #5
0
def PSF(NA=1.2, n=1.46, sampling_z=None, shape_z=None):
    """ create an out of focus PSF
    """
    args = {
        'shape': (128, 128),  # number of samples in z and r direction
        'dims': (5.0, 5.0),  # size in z and r direction in micrometers
        'ex_wavelen': 488.0,  # excitation wavelength in nanometers
        'em_wavelen': 532.0,  # emission wavelength in nanometers
        'num_aperture': NA,
        'refr_index': n,
        'magnification': 1.0,
        #    'pinhole_radius': 0.05,  # in micrometers
        #    'pinhole_shape': 'square',
    }

    if shape_z != None:
        args["shape"] = [shape_z, args["shape"][1]]

    abbe_r = args["em_wavelen"] / (2 * args["num_aperture"])
    sampling_r = abbe_r / 2.2
    dim_r = sampling_r * args['shape'][1] / 1000
    #1.2 for a bit of oversampling

    if sampling_z == None:
        alpha = np.arcsin(args["num_aperture"] / args["refr_index"])
        abbe_z = args["em_wavelen"] / (1 - np.cos(alpha))
        sampling_z = abbe_z / 2.2

    dim_z = sampling_z * args['shape'][0] / 1000

    args["dims"] = [dim_z, dim_r]

    obsvol = psf.PSF(psf.ISOTROPIC | psf.WIDEFIELD, **args)
    empsf = obsvol.empsf

    #    empsf.slice(100)

    #    #def Main():
    #    params = {
    #       'figure.figsize': [8, 6],
    #       'legend.fontsize': 12,
    #       'text.usetex': False,
    #       'ytick.labelsize': 10,
    #       'ytick.direction': 'out',
    #       'xtick.labelsize': 20,
    #       'xtick.direction': 'out',
    #       'font.size': 10,
    #       }
    ##    mpl.rcParams.update(params)
    #
    #
    #    title_font = {'fontname':'Arial', 'size':'16', 'color':'black', 'weight':'normal',
    #      'verticalalignment':'bottom'} # Bottom vertical alignment for more space
    #    axis_font = {'fontname':'Arial', 'size':'18'}

    #    plt.imshow(empsf.slice(100))

    args["sampling"] = [sampling_z, sampling_r]

    return empsf, args
예제 #6
0
파일: pipeline.py 프로젝트: ahstewart/OASIS
def pipeline_run_sim(path, sim_x=1, sim_y=1, sim_width=30, sim=True):
    import align_astroalign
    from ref_image import ref_image
    import combine_swarp
    import extract
    import subtract
    import mask
    import sys
    import psf
    import MR
    import os
    import time
    startTime = time.time()
    if os.path.exists(path) == True:
        location = path + '/data'
        ref_image(location)
        align_astroalign.align2(location)
        mask.MASK(path)
        print("-> Combining images using swarp method...")
        psf.PSF(path)
        combine_swarp.swarp(location)
        psf.PSF(path)
        print("\n-> Subtracting images...")
        subtract.SUBTRACT(path)
        #        print("\n-> Subtracting images using AIS method...")
        #        subtract_ais.isis_sub(path)
        #        optimize.perform_optimization(path, s_x=sim_x, s_y=sim_y, s_width=sim_width, simulate=sim, qFloor=0.80, qValue=0.90, qInitial=0.95, use_config_file=False)
        print("-> Running SExtractor on residuals...")
        extract.EXTRACT(path, method='indiv')
        MR.MR(path)
        extract.EXTRACT(path, method='MR')
        endTime = time.time()
        print("-> Finished!\n-> Total runtime: %.2f seconds\n" %
              (endTime - startTime))
    else:
        print(
            "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n"
        )
        sys.exit()
예제 #7
0
def psf_volume(voxel_dim, expansion, fluorophore, laser_wavelength, numerical_aperture,\
                refractory_index, pinhole_radius, objective_factor, type, **kwargs):
    """
    Creates a point spread volume, using the given parameters.
    
    Args:
        voxel_dim: (z, x, y) tuple
            the dimensions of a voxel in nm
        expansion: float
            the expansion factor
        fluorophore: string
            the fluorophore that is excited
        laser_wavelength: int
            the wavelength of the excitation laser in nm
        numerical_aperture:
            the numerical aperture of the system
        refractory_index:
            the refractory index, tipically 1.33 for ExM
        pinhole_radius:
            the pinhole raids in microns
        objective_factor: float
            objective factor of the microscope, tipically 0, 20 or 40
        type: string
            one of 'confocal', 'widefield' or 'two photon'
    Returns:
        psf_vol: numpy 3d float64 array
            the point spread function
    """
    fluorset = Fluorset()
    f = fluorset.get_fluor(fluorophore)
    #Map to psf type
    psf_type = {
        'confocal': psf.CONFOCAL,
        'widefield': psf.WIDEFIELD,
        'two photon': psf.TWOPHOTON
    }
    #Upper bound for psf size
    precision = 16
    z, x, y = np.array(voxel_dim) * expansion
    #Arguments
    back_projected_radius = pinhole_radius / float(objective_factor)
    #Fill args in dictionary
    args = dict(shape=(precision, precision), dims=(precision * z * 1e-3, precision * x * 1e-3),\
                ex_wavelen=laser_wavelength, em_wavelen=f.find_emission_peak(),\
                num_aperture=numerical_aperture, refr_index=refractory_index,\
                pinhole_radius=back_projected_radius, magnification = 1)
    #Compute psf
    psf_vol = psf.PSF(psf.ISOTROPIC | psf_type[type], **args)
    return psf_vol.volume()
예제 #8
0
def SUBTRACT(path, method='ois', use_config_file=True):
    '''Performs difference imaging on the science images. The template image is convolved to match the science image's PSF, then the template is subtracted from the science image.
    This process is repeated for a number of different parameter configurations until an optimal residual is found.
    The actual convolution and subtraction is done with either the ``ISIS`` package (Alard) or ``hotpants`` (Becker). See documentation for details.
    
    :param str path: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets.
    :param str method: Method of difference imaging.
    :param bool use_config_file: If ``True`` all input parameters are fetched from the local *OASIS.config* file.
    
        * *ois* (default): Optimal Image Subtraction. Christohpe Alard's ``ISIS`` package.
        * *hotpants*: Andrew Becker's ``hotpants`` program. Very similar to Alard's OIS, but differs in input parameters. May be useful to try if OIS is returning inadequate results. 
    
    :returns: All science images are differenced and the corresponding residuals are placed in the **residuals** directory with the *_residual_* suffix.
    
    '''
    paths = (path.replace(' ', '')).split(',')
    del path
    for path in paths:
        if use_config_file == True:
            method = get_config_value('sub_method')
        images = glob.glob(path + '/data/*.fits')
        psf_data = glob.glob(path + '/psf/*')
        if len(psf_data) != 2 * (len(images) + 1):
            psf.PSF(path)
        else:
            print("\n-> PSFs already exist...")
        if method == '' or method == 'ois':
            subtract_ais.isis_sub(path)
            optimize.perform_optimization(path)
            MR.MR_swarp(path)
        elif sub_method == 'hotpants':
            subtract_hotpants.hotpants(path)
            optimize.perform_optimization(path)
            MR.MR_swarp(path)
        else:
            print("\n-> Error: Unknown method")
            sys.exit()
예제 #9
0
def psf_generator(cmap='hot', savebin=False, savetif=False, savevol=False, plot=False, display=False, psfvol=False, psftype=0, expsf=False, empsf=False, realshape=(0,0), **kwargs):
	"""Calculate and save point spread functions."""

	args = {
		'shape': (50, 50),  # number of samples in z and r direction
		'dims': (5.0, 5.0),   # size in z and r direction in micrometers
		'ex_wavelen': 488.0,  # excitation wavelength in nanometers
		'em_wavelen': 520.0,  # emission wavelength in nanometers
		'num_aperture': 1.2,
		'refr_index': 1.333,
		'magnification': 1.0,
		'pinhole_radius': 0.05,  # in micrometers
		'pinhole_shape': 'round',
	}
	args.update(kwargs)

	if (psftype == 0):
		psf_matrix = psf.PSF(psf.ISOTROPIC | psf.EXCITATION, **args)
		print('psf.ISOTROPIC | psf.EXCITATION generated')
	if (psftype == 1):
		psf_matrix = psf.PSF(psf.ISOTROPIC | psf.EMISSION, **args)
		print('psf.ISOTROPIC | psf.EMISSION generated')
	if (psftype == 2):
		psf_matrix = psf.PSF(psf.ISOTROPIC | psf.WIDEFIELD, **args)
		print('psf.ISOTROPIC | psf.WIDEFIELD generated')
	if (psftype == 3):
		psf_matrix = psf.PSF(psf.ISOTROPIC | psf.CONFOCAL, **args)
		print('psf.ISOTROPIC | psf.CONFOCAL generated')
	if (psftype == 4):
		psf_matrix = psf.PSF(psf.ISOTROPIC | psf.TWOPHOTON, **args)
		print('psf.ISOTROPIC | psf.TWOPHOTON generated')
	if (psftype == 5):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.EXCITATION, **args)
		print('psf.GAUSSIAN | psf.EXCITATION generated')
	if (psftype == 6):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.EMISSION, **args)
		print('psf.GAUSSIAN | psf.EMISSION generated')
	if (psftype == 7):
		print('psf.GAUSSIAN | psf.WIDEFIELD generated')
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.WIDEFIELD, **args)
	if (psftype == 8):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.CONFOCAL, **args)
		print('psf.GAUSSIAN | psf.CONFOCAL generated')
	if (psftype == 9):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.TWOPHOTON, **args)
		print('psf.GAUSSIAN | psf.TWOPHOTON generated')
	if (psftype == 10):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.EXCITATION | psf.PARAXIAL, **args)
		print('psf.GAUSSIAN | psf.EXCITATION | psf.PARAXIAL generated')
	if (psftype == 11):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.EMISSION | psf.PARAXIAL, **args)
		print('psf.GAUSSIAN | psf.EMISSION | psf.PARAXIAL generated')
	if (psftype == 12):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.WIDEFIELD | psf.PARAXIAL, **args)
		print('psf.GAUSSIAN | psf.WIDEFIELD | psf.PARAXIAL generated')
	if (psftype == 13):
		print('psf.GAUSSIAN | psf.CONFOCAL | psf.PARAXIAL generated')
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.CONFOCAL | psf.PARAXIAL, **args)
	if (psftype == 14):
		psf_matrix = psf.PSF(psf.GAUSSIAN | psf.TWOPHOTON | psf.PARAXIAL, **args)
		print('psf.GAUSSIAN | psf.TWOPHOTON | psf.PARAXIAL generated')
	
	if empsf:
		psf_matrix = psf_matrix.expsf
	if expsf:
		psf_matrix = psf_matrix.empsf
		
	
	if psfvol:
		psf_matrix = normalize_matrix(psf_matrix.volume())
		psf_matrix = psf_matrix[:realshape[0],:,:]
		psf_matrix = psf_matrix[:,:realshape[1],:realshape[1]]
	else: 
		#psf_matrix = normalize_matrix(psf.mirror_symmetry(psf_matrix.data))
		psf_matrix = psf.mirror_symmetry(psf_matrix.data)
		psf_matrix = psf_matrix[:realshape[1],:realshape[1]]
	
	if plot:
		import matplotlib.pyplot as plt
		plt.imshow(psf_matrix, cmap=cmap)
		plt.show()
	
	if display:
		import cv2
		cv2.imshow('PSF',psf_matrix)
		cv2.waitKey(0)
		cv2.destroyAllWindows()

	if savetif:
		# save zr slices to TIFF files
		from tifffile import imsave
		
		imsave('psf_matrix.tif', psf_matrix, metadata = {'axes':'TZCYX'}, imagej=True)

	if savevol:
		# save xyz volumes to files.
		from tifffile import imsave
		
		imsave('psf_matrix_vol.tif', psf_matrix,  metadata = {'axes':'TZCYX'}, imagej=True)
		
	print('PSF shape: ', psf_matrix.shape)
	return psf_matrix
예제 #10
0
 def __init__(self, kernel_shape=7, multiple=5):
     self.kernel_shape = kernel_shape
     self.multiple = multiple
     self.psf_gen = psf.PSF(kernel_size=kernel_shape)
예제 #11
0
def TEST():
    '''Tests the installation of **OasisPy** by downloading a set of images from an online public archive, adding fake sources to one of the images, and running the dataset through the **OASIS Pipeline**.
    If the fake sources are recovered, the test is a success. The images used are 118 second exposures of exoplanet HAT-P-37b taken with telescopes at the Las Cumbres Observatory.
    Results of the test are compared to control results located in **OasisPy**'s source code directory.
    
    :returns: Prints either 'TEST SUCCESSFUL!' or 'Test failure: Results do not match controls'.
    
    '''
    frameNum = 30
    q_initial = 1
    q_value = 0.90
    q_min = 0.80
    startTime = time.time()
    #look for existing TEST folder and delete it
    og_test = loc + '/OASIS/targets/TEST'
    if os.path.exists(og_test) == True:
        shutil.rmtree(og_test)
    #get data from LCO public archive and put in target directory under 'TEST' folder
    print("\n-> Getting data from LCO...")
    object_name = 'HAT-P-37'
    response = requests.get('https://archive-api.lco.global/frames/?' +
                            'limit=%d&' % (frameNum) + 'RLEVEL=91&' +
                            'PROPID=' + 'LCOEPO2014B-007' + '&' + 'OBJECT=' +
                            '%s&' % (object_name) + 'FILTER=' + 'w&' +
                            'start=' + '2019-05-29' + '&'
                            'end=' + '2019-05-31' + '&').json()

    frames = response['results']
    #    print(len(frames))

    #take only the first 25 frames
    frames = frames[:frameNum]

    #download data
    temp_loc = loc + '/OASIS/temp/'
    os.mkdir(temp_loc + 'test_data')
    for frame in frames:
        with open(temp_loc + 'test_data/' + frame['filename'], 'wb') as f:
            f.write(requests.get(frame['url']).content)

    #funpack and move to 'TEST' folder
    obtain.process()
    obtain.movetar()
    old_data_location = obtain.rename()
    data_location = old_data_location.replace(object_name.replace(' ', '_'),
                                              'TEST')
    os.rename("%s/OASIS/targets/%s" % (loc, object_name.replace(' ', '_')),
              "%s/OASIS/targets/TEST" % (loc))

    #align and combine images
    test_loc = data_location[:-5]
    mask.MASK(test_loc)
    check_saturation.check_saturate(test_loc + '/data')
    ref_image.ref_image(test_loc + '/data')
    align_astroalign.align2(test_loc + '/data')
    psf.PSF(test_loc)
    combine_swarp.swarp(test_loc + '/data')

    #get PSFs of images so fake stars with same seeing can be added
    fake_im = '02:59:10.860_A_.fits'
    print('\n-> Image %s chosen as fake image\n' % (fake_im))
    fake_residual = fake_im.replace('_A_', '_A_residual_')
    psf.PSF(test_loc)
    FWHM = psf.fwhm(test_loc + '/data/%s' % (fake_im))

    #add three fake stars to reference image
    print("\n-> Adding fake stars to test image...")
    hdu = fits.open(test_loc + '/data/%s' % (fake_im))
    hdu_data = hdu[0].data
    hdu_header = hdu[0].header
    hdu_mask = hdu[1].data

    h, w = np.shape(hdu_data)
    pos_x = [1500, 200, 1200]
    pos_y = [1600, 1400, 700]
    array = np.array([0.65343465, 0.50675629, 0.84946314])
    fluxes = (200000.0 * array) + 300.0
    print("\n-> Fake locations (in pixel coords):")
    print("\t X:", pos_x)
    print("\t Y:", pos_y)
    print("-> Fake fluxes (in ADUs):")
    print("\t ", fluxes)

    img = make_gaussian_im(h,
                           w,
                           fluxes=[fluxes[0], fluxes[1], fluxes[2]],
                           x_pos=[pos_x[0], pos_x[1], pos_x[2]],
                           y_pos=[pos_y[0], pos_y[1], pos_y[2]],
                           std=[FWHM, FWHM, FWHM])

    finalData = fits.PrimaryHDU(hdu_data + img, header=hdu_header)
    finalMask = fits.ImageHDU(hdu_mask)
    finalList = fits.HDUList([finalData, finalMask])
    finalList.writeto(test_loc + '/data/%s' % (fake_im), overwrite=True)
    hdu.close()

    #subtract images using ISIS
    subtract_ais.isis_sub(test_loc)
    perform_optimization(test_loc,
                         qInitial=q_initial,
                         qValue=q_value,
                         qFloor=q_min,
                         use_config_file=False)
    MR.MR_swarp(test_loc)

    #perform SExtractor on residual images
    extract.EXTRACT(test_loc)

    #print TEST runtime
    endTime = time.time()
    print("\n-> Total test runtime: %.3fs\n" % (endTime - startTime))

    residual = glob.glob(test_loc + '/residuals/%s' % (fake_residual))

    fake1_check = False
    fake2_check = False
    fake3_check = False

    MR_sources, inds = filters.get_sources("%s/residuals/MR.fits" % (test_loc),
                                           filtered=True,
                                           MR=True)
    for src in MR_sources:
        if 1498 < src[1] < 1502 and 1598 < src[2] < 1602:
            fake1_check = True
        elif 198 < src[1] < 202 and 1398 < src[2] < 1402:
            fake2_check = True
        elif 1198 < src[1] < 1202 and 698 < src[2] < 702:
            fake3_check = True

    if fake1_check == True and fake2_check == True and fake3_check == True:
        print("\n-> Test SUCCESSFUL!")
    else:
        print("-> Test failure: Results do not match controls")

    #display final residual test image
    os.system('ds9 %s -scale zscale' % (residual[0]))
예제 #12
0
def psf_example(cmap='hot',
                savebin=False,
                savetif=False,
                savevol=False,
                plot=True,
                **kwargs):
    """Calculate, save, and plot various point spread functions."""

    args = {
        'shape': (512, 512),  # number of samples in z and r direction
        'dims': (5.0, 5.0),  # size in z and r direction in micrometers
        'ex_wavelen': 488.0,  # excitation wavelength in nanometers
        'em_wavelen': 520.0,  # emission wavelength in nanometers
        'num_aperture': 1.2,
        'refr_index': 1.333,
        'magnification': 1.0,
        'pinhole_radius': 0.05,  # in micrometers
        'pinhole_shape': 'square',
    }
    args.update(kwargs)

    obsvol = psf.PSF(psf.ISOTROPIC | psf.CONFOCAL, **args)
    expsf = obsvol.expsf
    empsf = obsvol.empsf
    gauss = gauss2 = psf.PSF(psf.GAUSSIAN | psf.EXCITATION, **args)

    print(expsf)
    print(empsf)
    print(obsvol)
    print(gauss)
    print(gauss2)

    if savebin:
        # save zr slices to BIN files
        empsf.data.tofile('empsf.bin')
        expsf.data.tofile('expsf.bin')
        gauss.data.tofile('gauss.bin')
        obsvol.data.tofile('obsvol.bin')

    if savetif:
        # save zr slices to TIFF files
        from tifffile import imsave

        imsave('empsf.tif', empsf.data)
        imsave('expsf.tif', expsf.data)
        imsave('gauss.tif', gauss.data)
        imsave('obsvol.tif', obsvol.data)

    if savevol:
        # save xyz volumes to files. Requires 32 GB for 512x512x512
        from tifffile import imsave

        imsave('empsf_vol.tif', empsf.volume())
        imsave('expsf_vol.tif', expsf.volume())
        imsave('gauss_vol.tif', gauss.volume())
        imsave('obsvol_vol.tif', obsvol.volume())

    if not plot:
        return

    # Log-plot xy, and rz slices
    pyplot.rc('font', family='sans-serif', weight='normal')
    pyplot.figure(dpi=96,
                  figsize=(9.5, 5.0),
                  frameon=True,
                  facecolor='w',
                  edgecolor='w')
    pyplot.subplots_adjust(bottom=0.02,
                           top=0.92,
                           left=0.02,
                           right=0.98,
                           hspace=0.01,
                           wspace=0.01)

    ax = expsf.imshow(241, cmap=cmap)[0]
    empsf.imshow(242, sharex=ax, sharey=ax, cmap=cmap)
    obsvol.imshow(243, sharex=ax, sharey=ax, cmap=cmap)
    gauss.imshow(244, sharex=ax, sharey=ax, cmap=cmap)
    z = 0
    psf.imshow(245, data=expsf.slice(z), sharex=ax, cmap=cmap)
    psf.imshow(246, data=empsf.slice(z), sharex=ax, cmap=cmap)
    psf.imshow(247, data=obsvol.slice(z), sharex=ax, cmap=cmap)
    psf.imshow(248, data=gauss.slice(z), sharex=ax, cmap=cmap)

    # plot cross sections
    z = numpy.arange(0, gauss.dims.ou[0], gauss.dims.ou[0] / gauss.dims.px[0])
    r = numpy.arange(0, gauss.dims.ou[1], gauss.dims.ou[1] / gauss.dims.px[1])
    zr_max = 20.0
    pyplot.figure()
    pyplot.subplot(211)
    pyplot.title('PSF cross sections')
    pyplot.plot(r, expsf[0], 'r-', label=expsf.name + ' (r)')
    pyplot.plot(r, gauss2[0], 'r:', label='')
    # pyplot.plot(r, empsf.data[0], 'g--', label=empsf.name+' (r)')
    pyplot.plot(r, obsvol[0], 'b-', label=obsvol.name + ' (r)')
    pyplot.plot(r, gauss[0], 'b:', label="")
    pyplot.plot(z, expsf[:, 0], 'm-', label=expsf.name + ' (z)')
    pyplot.plot(z, gauss2[:, 0], 'm:', label='')
    # pyplot.plot(z, empsf.data[:,0], 'g--', label=empsf.name+' (z)')
    pyplot.plot(z, obsvol[:, 0], 'c-', label=obsvol.name + ' (z)')
    pyplot.plot(z, gauss[:, 0], 'c:', label='')
    pyplot.legend()
    pyplot.axis([0, zr_max, 0, 1])
    pyplot.subplot(212)
    pyplot.title('Residuals of gaussian approximation')
    pyplot.plot(r, expsf[0] - gauss2[0], 'r-', label=expsf.name + ' (r)')
    pyplot.plot(r, obsvol[0] - gauss[0], 'b-', label=obsvol.name + ' (r)')
    pyplot.plot(z, expsf[:, 0] - gauss2[:, 0], 'm-', label=expsf.name + ' (z)')
    pyplot.plot(z,
                obsvol[:, 0] - gauss[:, 0],
                'c-',
                label=obsvol.name + ' (z)')
    pyplot.axis([0, zr_max, -0.1, 0.1])
    pyplot.tight_layout()

    pyplot.show()
예제 #13
0
def RUN():
    '''
    Master run function. Allows user to call any of the main **OASIS** methods. See documentation for details.
    '''
    print('\n\t ------------------------------------------------------')
    print('\t                     OASIS  v.1.0                       ')
    print('\n\t  Difference Imaging Software for Optical SETI Purposes  ')
    print('\t           Developed for the SDI Program @ UCSB          ')
    print('\t              http://www.deepspace.ucsb.edu              ')
    print('\n\t Contact [email protected] for bug reports  ')
    print('\t ------------------------------------------------------')
    print("\n-> Methods:")
    print("\n\tinitialize    get        mask        align")
    print("\tpsf           combine    subtract    mr")
    print("\textract       pipeline   simulate    test")
    method = str(input('\n-> Enter method: '))
    if method == 'get':
        import get
        get.GET()
    elif method == 'mask':
        path = input("-> Enter path to exposure time directory: ")
        import mask
        mask.MASK(path)
    elif method == 'align':
        path = input("-> Enter path to exposure time directory: ")
        import align
        align.ALIGN(path)
    elif method == 'psf':
        path = input("-> Enter path to exposure time directory: ")
        import psf
        psf.PSF(path)
    elif method == 'combine':
        path = input("-> Enter path to exposure time directory: ")
        import combine
        combine.COMBINE(path)
    elif method == 'subtract':
        path = input("-> Enter path to exposure time directory: ")
        import subtract
        subtract.SUBTRACT(path)
    elif method == 'mr':
        path = input("-> Enter path to exposure time directory: ")
        import MR
        MR.MR(path)
    elif method == 'extract':
        import extract
        path = input("-> Enter path to exposure time directory: ")
        extract_method = input("\n-> Extract method (both/indiv/MR): ")
        extract.EXTRACT(path, method=extract_method)
    elif method == 'pipeline':
        import pipeline
        path = input("-> Enter path to exposure time directory: ")
        pipeline.PIPELINE(path)
    elif method == 'initialize':
        import initialize
        initialize.INITIALIZE()
    elif method == 'test':
        import test
        test.TEST()
    elif method == 'simulate':
        import simulation
        simulation.SIM()
    else:
        print("-> Error: Method not recognized")
예제 #14
0
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Patrick Wieschollek <*****@*****.**>

from build import blur_library
import cv2
import psf
import numpy as np

img = cv2.imread('input.jpg')
img = img.astype(np.float32) / 255.

psf = psf.PSF(kernel_size=17)
k = next(psf.sample()).astype(np.float32)


def single_image_blur(img, k, gpu_id=0):
    """Apply PSF to images on the GPU usin cuDNN

    Args:
        img (nd.array.float32): image in shape [H,W,C]
        k (nd.array.float32): kernel in shape [H,W]
    """

    output = img.astype(np.float32).transpose((2, 0, 1)).copy()
    k = k.astype(np.float32)
    blur_library.blur(output, k, gpu_id)
    return output.transpose((1, 2, 0))


def batch_image_blur(img, k, gpu_id=0):
예제 #15
0
def get_PSF(stack, imagepath, conn, scriptParams):
	#Prepare the PSF for the deconvolution
	imageId = stack.getId()
	
	if scriptParams["Type_of_PSF"] == 'Measured PSF':
		#If a PSF is supplied, find the measured PSF and download it in the deconvolution folder.
		
		psfId = scriptParams["Measured_PSF_Image"]
		try:
			obs = conn.getObject("Image", psfId)
		except AttributeError:
			raise("The image supplied for the PSF (image %s) is not valid." %psfId)
		download(obs,str(imageId)+"PSF", 0, imagepath)
	
	
	else:
		#If no measured PSF is supplied, the theoretical PSF must be calculated. 
		
		#Option1: Manually enter PSF parameters
		#Option2: Use OMERO metadata
		
		#First, prepare all the parameters that will be shared between the two options
		args = {}
		channelExcitation = []
		channelEmission = []
		sizeC = 0
		sizeX = stack.getPrimaryPixels().getSizeX()
		pixelX = stack.getPrimaryPixels().getPhysicalSizeX().getValue()
		
		#The PSF parameters are passed to psf.py through the args dictionary
		args["shape"] = (int(round(sizeX / 2)+1), int(round(sizeX / 2))+1) #Need to divide by 2 and add 1 to get the right final number of pixels
		args["dims"] = (int(round(pixelX * sizeX / 2)), int(round(pixelX * sizeX / 2))) #Because of the previous operation the PSF will be inconsequentially too small (1/x) and off-centered.
		args["pinhole_radius"] = 0.55 #default value
		args["pinhole_shape"] = 'round' #the Olympus FV1200 confocal's pinhole is square
		
		
		#Option 1: Manual PSF
		if scriptParams["Type_of_PSF"] == 'Manual theoretical PSF':
			
			fluoType = scriptParams["Fluorescence_Microscopy_"]
			
			args["pinhole_radius"] = scriptParams["Confocal_Pinhole______"]
			args["num_aperture"] = scriptParams["Objective_NA_____________"]
			
			if scriptParams["Imaging_Medium_________"] == 'Oil':
				args["refr_index"] = 1.515
			elif scriptParams["Imaging_Medium_________"] == 'Water':
				args["refr_index"] = 1.333
			elif scriptParams["Imaging_Medium_________"] == 'Air':
				args["refr_index"] = 1.0
			elif scriptParams["Imaging_Medium_________"] == 'CLARITY':
				args["refr_index"] = 1.45
				
			if scriptParams["_____Channel_1_-_Excitation"] !=0:
				sizeC += 1
				channelExcitation.append(scriptParams["_____Channel_1_-_Excitation"])
				channelEmission.append(scriptParams["_____Channel_1_-_Emission__"])
			
			if scriptParams["_____Channel_2_-_Excitation"] !=0:
				sizeC += 1
				channelExcitation.append(scriptParams["_____Channel_2_-_Excitation"])
				channelEmission.append(scriptParams["_____Channel_2_-_Emission__"])
			
			if scriptParams["_____Channel_3_-_Excitation"] !=0:
				sizeC += 1
				channelExcitation.append(scriptParams["_____Channel_3_-_Excitation"])
				channelEmission.append(scriptParams["_____Channel_3_-_Emission__"])
			
			if sizeC != stack.getSizeC():
				raise ValueError("Wrong number of PSF channels parameters set. Make sure to set the right number of channels.")
		
		
		#Option 2: Automatic PSF. (Uses the metadata from the stack. Whether this will work depends on the metadata.)
		else:	
		
			try:
				objective = stack.getObjectiveSettings().getObjective().getModel()
			except AttributeError:
				raise ("Couldn't identify the objective used for image %s. Please use the manual PSF settings." %imageId)

			try:
				args["num_aperture"] = stack.getObjectiveSettings().getObjective().getLensNA()
			except AttributeError:
				raise ("Couldn't find the numerical aperture for the objective used for image %s. Please use the manual PSF settings." %imageId)
				
			#Deduce immersion and microscopy type through the objective used:
			if objective in {"XLSLPLN25XGMP","XLPLN10XSVMP"}: #Two-photon CLARITY objectives
				fluoType = "TWOPHOTON"
				args["refr_index"] = 1.48
			elif objective in {"XLPLN25XWMP2", "XLUMPLFLN-W"}: #Two-photon water objectives #need to double check the metadata name of the XLUM objective
				fluoType = "TWOPHOTON"
				args["refr_index"] = 1.333
			elif objective == "PLAPON    60X O  NA:1.42": #Confocal oil objectives
				fluoType = "CONFOCAL"
				args["refr_index"] = 1.515
				args["pinhole_radius"] = 1 #TODO Figure out which metadata setting to select for pinhole_radius
			
				#TODO add air and widefield objectives	
			
			else:
				raise AttributeError("Couldn't identify the objective used for image %s. Please use the manual PSF settings." %imageId)
			
			for c in stack.getChannels():
				channel = c.getLogicalChannel()
				try:
					channelExcitation.append(channel.getExcitationWave().getValue())
					channelEmission.append(channel.getEmissionWave().getValue())
				except AttributeError:
					raise ("Couldn't find the excitation or emission wavelength of Channel %s from image %s. Please use the manual PSF settings." %(c,imageID))
			
			sizeC = stack.getSizeC()			
		
		#Calculate the PSF.
		for c in range(sizeC): #Loop through all channels since each one has a different theoretical PSF
		
			args["ex_wavelen"] = channelExcitation[c]
			args["em_wavelen"] = channelEmission[c]
			
			#This is the step where the image of the theoretical PSF is produced
			if fluoType == "TWOPHOTON":
				obsvol = psf.PSF(psf.GAUSSIAN | psf.TWOPHOTON, **args) #The settings are supplied through the args dictionary
			elif fluoType == "CONFOCAL":
				obsvol = psf.PSF(psf.GAUSSIAN | psf.CONFOCAL, **args)
			elif fluoType == "WIDEFIELD":
				obsvol = psf.PSF(psf.GAUSSIAN | psf.WIDEFIELD, **args)
			
			#The PSF needs to be completed with the mirror_symmetry function and corrected because it's produced with 
			#one extra row and one extra column of pixels; we need to shave off those two extra lines. This doesn't seem ideal but this 
			#is the recommandation from C. Gohlke and AIDA centers the PSF anyway.
			image_psf = psf.mirror_symmetry(obsvol.slice(0)) 
			image_psf = np.delete(image_psf,1,0) 
			image_psf = np.delete(image_psf,1,1) 
			
			#Donwload the PSF. This is the same operation as the download function
			pixels = image_psf.astype(np.float32)
			tiff = Image.fromarray(pixels)
			deconv_path = os.path.join(imagepath, "%s%s_C%s_%03d_%03d.tif" % (imageId,"PSF",c,0,0))
			tiff.save(deconv_path)