Example #1
0
def norm_and_guess(transimg, norm=True):
    """Normalize the transmission image and find initial fitting parameters"""

    odimg = trans2od(transimg)
    # determine CoM to use as parameter in fitting of n2D_radial to odimg
    com = center_of_mass(odimg)

    # guess initial fit parameters
    n0 = odimg[com[0] - 5:com[0] + 5,
               com[1] - 5:com[1] + 5].sum() * 1e-2  # av. central OD
    a = 4  # log(fugacity)

    # approximate cloud size, with minimum 10 pixels in case this does not work
    # use something better, like moment estimation!
    # for elliptical clouds this is way off, and for low OD it fails!
    bprime = 0.5 * (threshold_image(
        odimg.mean(axis=1), thres=0.1 * n0, below=False)).sum()
    bprime = max(bprime, 10)

    # normalize the background
    if norm:
        try:
            transimg = normalize_img(transimg, com, bprime)
        except NotImplementedError:
            print "Couldn't normalize the image"

    # this maxod is specific to each experiment and needs to be checked
    odimg = trans2od(transimg, maxod=3)
    com = center_of_mass(odimg)

    return transimg, odimg, com, n0, a, bprime
Example #2
0
def norm_and_guess(transimg, norm=True):
    """Normalize the transmission image and find initial fitting parameters"""

    odimg = trans2od(transimg)
    # determine CoM to use as parameter in fitting of n2D_radial to odimg
    com = center_of_mass(odimg)

    # guess initial fit parameters
    n0 = odimg[com[0]-5:com[0]+5, com[1]-5:com[1]+5].sum()*1e-2 # av. central OD
    a = 4 # log(fugacity)

    # approximate cloud size, with minimum 10 pixels in case this does not work
    # use something better, like moment estimation!
    # for elliptical clouds this is way off, and for low OD it fails!
    bprime = 0.5*(threshold_image(odimg.mean(axis=1), thres=0.1*n0, below=False)).sum()
    bprime = max(bprime, 10)

    # normalize the background
    if norm:
        try:
            transimg = normalize_img(transimg, com, bprime)
        except NotImplementedError:
            print "Couldn't normalize the image"

    # this maxod is specific to each experiment and needs to be checked
    odimg = trans2od(transimg, maxod=3)
    com = center_of_mass(odimg)

    return transimg, odimg, com, n0, a, bprime
Example #3
0
def find_ellipticity(transimg, normalize=True, tol=2e-3):
    """Determines the ellipticity of an atom cloud

    The ellipticity is found by an optimization routine. A value is tried
    and the sum of residuals between the radial line profiles and the averaged
    result is computed. This value is then minimized. This method is accurate
    but slow. An alternative option is to use the second moments of the image.

    **Inputs**

      * transimg: 2D array, containing the absorption image
      * normalize: bool, if True transimg is normalized with norm_and_guess(),
                   otherwise the odimg is obtained directly from transimg.
      * tol: float, the required tolerance

    **Outputs**

      * ellip: float, the ellipticity of the atom cloud

    """

    if normalize:
        transimg, odimg, com, n0, a, bprime = norm_and_guess(transimg)
    else:
        odimg = trans2od(transimg)
        com = center_of_mass(odimg)

    def ellipticity(ell):
        rcoord, rad_profile, rprofiles, angles = radial_interpolate(odimg, com,\
                                    0.3, elliptic=(ell, 0), full_output=True)

        od_cutoff = find_fitrange(rad_profile)
        av_err = radialprofile_errors(rprofiles, angles, rad_profile, \
                                        od_cutoff, showfig=False, report=False)

        return av_err

    ellip = sp.optimize.fminbound(ellipticity, 0.6, 1.0, full_output=0, \
                                  xtol=tol)
    print 'ellipticity = %1.3f'%ellip

    return ellip
Example #4
0
def find_ellipticity(transimg, normalize=True, tol=2e-3):
    """Determines the ellipticity of an atom cloud

    The ellipticity is found by an optimization routine. A value is tried
    and the sum of residuals between the radial line profiles and the averaged
    result is computed. This value is then minimized. This method is accurate
    but slow. An alternative option is to use the second moments of the image.

    **Inputs**

      * transimg: 2D array, containing the absorption image
      * normalize: bool, if True transimg is normalized with norm_and_guess(),
                   otherwise the odimg is obtained directly from transimg.
      * tol: float, the required tolerance

    **Outputs**

      * ellip: float, the ellipticity of the atom cloud

    """

    if normalize:
        transimg, odimg, com, n0, a, bprime = norm_and_guess(transimg)
    else:
        odimg = trans2od(transimg)
        com = center_of_mass(odimg)

    def ellipticity(ell):
        rcoord, rad_profile, rprofiles, angles = radial_interpolate(odimg, com,\
                                    0.3, elliptic=(ell, 0), full_output=True)

        od_cutoff = find_fitrange(rad_profile)
        av_err = radialprofile_errors(rprofiles, angles, rad_profile, \
                                        od_cutoff, showfig=False, report=False)

        return av_err

    ellip = sp.optimize.fminbound(ellipticity, 0.6, 1.0, full_output=0, \
                                  xtol=tol)
    print 'ellipticity = %1.3f' % ellip

    return ellip
Example #5
0
def generate_report(rawframes, transimg, img_name, pixcal, showpdf=True):
    """Generate a report with several image diagnostics

    The report comes in the form of a pdf file that has the name
    ``img_name``.pdf and is put in the same directory as the image.

    **Inputs**

      * rawframes: 3D array, containing the three raw frames
      * transimg: 2D array, containing the transmission image (properly ROIed)
      * img_name: string, the name of the image
      * pixcal: float, pixel size calibration in m/pix.
      * showpdf: bool, if True Acrobat Reader is launched to view the report

    """

    odimg = trans2od(transimg)
    com = center_of_mass(odimg)

    rawfig = show_rawframes(rawframes)
    savefig('trans_rawframes.jpg')
    close()

    ellip = find_ellipticity(transimg)
    ellip_figname = 'ellipfit'

    # figure out how good the ellipticity determination is and create polar plot
    rcoord, rad_profile, rprofiles, angles = radial_interpolate(odimg, com,\
                                    0.3, elliptic=(ellip, 0), full_output=True)
    od_cutoff = find_fitrange(rad_profile)
    av_err = radialprofile_errors(rprofiles, angles, rad_profile, od_cutoff, \
                        showfig=True, savefig_name=ellip_figname, report=False)

    # fit the image
    ToverTF, N, com, ans, rcoord, od_prof, fit_prof = fit_img(transimg, \
            showfig=False, elliptic=(ellip, 0), full_output='odysseus')
    # save the fit figure
    show_fitresult(rcoord, od_prof, fit_prof, ToverTF, N, figname='fitresult')

    # plot the residuals
    show_residuals(rcoord, od_prof, fit_prof, figname='residuals')
    fitresults = (ToverTF[0], N, ans[1], ans[2])

    # fit with several fixed temperatures
    ans_gaussian, ans2, temps = fit_several_fixedT(rcoord, od_prof, od_cutoff,
                                                   ans, ToverTF, pixcal)
    fig = plot_several_temp(rcoord, od_prof, fit_prof, ans, ans_gaussian, ans2,
                            pixcal)
    fig.savefig('several_temps.png')
    close(fig)

    # save a figure zoomed in around the wing of the distribution
    ind = round(ans2[0][2])
    istep = round(1./(rcoord[1]-rcoord[0]))*15
    ind = mpl.mlab.find(rcoord>ind).min()
    fig2 = plot_several_temp(rcoord[ind-istep:ind+istep], od_prof[ind-istep:ind+istep], \
                            fit_prof[ind-istep:ind+istep], ans, ans_gaussian,
                            ans2, pixcal)
    fig2.savefig('several_temps_zoomed.png')
    close(fig2)

    # create the report
    write_TeXreport('imgreport', img_name, ellip, ellip_figname, fitresults)
    print 'written TeX'
    pdfname = os.path.splitext(img_name)[0]
    TeX2pdf('imgreport', pdfname)
    print 'written pdf'

    # clean up image files
    pngfiles = ['ellipfit', 'fitresult', 'residuals', 'several_temps', \
                'several_temps_zoomed']
    for pngfile in pngfiles:
        try:
            os.unlink(''.join([pngfile, '.png']))
        except OSError:
            print "file %s.png does not exist, so can't clean it up" %pngfile

    jpgfiles = ['trans_rawframes']
    for jpgfile in jpgfiles:
        try:
            os.unlink(''.join([jpgfile, '.jpg']))
        except OSError:
            print "file %s.jpg does not exist, so can't clean it up" %jpgfile

    if showpdf:
        # launch acrobat reader with the report
        acrocmd = r"acroread %s.pdf" %re.sub(r" ", r"\ ", pdfname)
        acrocmd = re.sub(r";", r"\;", acrocmd)

        if platform.system()=='Windows':
            os.system(acrocmd)
        else:
            acrocmd = re.sub(r"acroread", r"xdg-open", acrocmd)
            os.system(acrocmd)

    return
Example #6
0
def add_noise(img, ampl=0.05, noisetype='random', fringeargs=None):
    """Noise is added to an image.

    **Inputs**

      * img: 2d array, containing image data
      * ampl: float, amplitude of the noise
      * noisetype: string, value can be one of

        * 'random', adds unbiased white noise
        * 'linear_x', adds a linear gradient along x from 0 to ampl
        * 'linear_y', adds a linear gradient along y from 0 to ampl
        * 'fringes', adds fringes with parameters fringeargs

      * fringeargs: sequence, containing four values

        * angle: float, angle of fringes in radians with respect to the x-axis
        * freq: float, frequency of the fringes in pixels^{-1}
        * pos: tuple, central position of the fringes with respect to the CoM
        * size: float, size of the Gaussian envelope of the fringes

    **Outputs**

      * img: 2d array, the input image with noise added to it

    """

    noisetypes = ['random', 'linear_x', 'linear_y', 'fringes']
    if not noisetype in noisetypes:
        raise ValueError, \
	      """noisetype is one of: %s"""%noisetypes

    if noisetype=='random':
        img = img + (np.random.random_sample(img.shape)-0.5)*ampl

    elif noisetype=='linear_x':
        noise = np.ones(img.shape).transpose()*np.arange(img.shape[0])\
              /img.shape[0]*ampl
        img = img + noise.transpose()

    elif noisetype=='linear_y':
        noise = np.ones(img.shape)*np.arange(img.shape[1])/img.shape[1]*ampl
        img = img + noise

    elif noisetype=='fringes':
        if not len(fringeargs)==4:
            print "fringeargs needs to contain four values: angle, freq, pos, size"
        angle, freq, pos, size = fringeargs
        xx, yy = np.mgrid[0:img.shape[0], 0:img.shape[1]]

        # center of mass coordinates
        odimg = trans2od(img)
        com = center_of_mass(odimg)
        xx0 = xx - com[0] - pos[0]
        yy0 = yy - com[1] - pos[1]
        yy0 = np.where(yy0==0, 1e-6, yy0)
        rr = np.sqrt(xx0**2 + yy0**2)

        # coordinate projection along fringe axis
        rangle = np.arctan(xx0.astype(float)/yy0)
        rangle = np.where(yy0>0, rangle, rangle + np.pi)
        rfringe = rr*np.cos(angle - rangle)

        noise = fitfuncs.gaussian(rr, ampl, size) * np.sin(2*np.pi*rfringe*freq)
        img = img + noise

    return img
Example #7
0
def add_noise(img, ampl=0.05, noisetype='random', fringeargs=None):
    """Noise is added to an image.

    **Inputs**

      * img: 2d array, containing image data
      * ampl: float, amplitude of the noise
      * noisetype: string, value can be one of

        * 'random', adds unbiased white noise
        * 'linear_x', adds a linear gradient along x from 0 to ampl
        * 'linear_y', adds a linear gradient along y from 0 to ampl
        * 'fringes', adds fringes with parameters fringeargs

      * fringeargs: sequence, containing four values

        * angle: float, angle of fringes in radians with respect to the x-axis
        * freq: float, frequency of the fringes in pixels^{-1}
        * pos: tuple, central position of the fringes with respect to the CoM
        * size: float, size of the Gaussian envelope of the fringes

    **Outputs**

      * img: 2d array, the input image with noise added to it

    """

    noisetypes = ['random', 'linear_x', 'linear_y', 'fringes']
    if not noisetype in noisetypes:
        raise ValueError, \
       """noisetype is one of: %s"""%noisetypes

    if noisetype == 'random':
        img = img + (np.random.random_sample(img.shape) - 0.5) * ampl

    elif noisetype == 'linear_x':
        noise = np.ones(img.shape).transpose()*np.arange(img.shape[0])\
              /img.shape[0]*ampl
        img = img + noise.transpose()

    elif noisetype == 'linear_y':
        noise = np.ones(img.shape) * np.arange(
            img.shape[1]) / img.shape[1] * ampl
        img = img + noise

    elif noisetype == 'fringes':
        if not len(fringeargs) == 4:
            print "fringeargs needs to contain four values: angle, freq, pos, size"
        angle, freq, pos, size = fringeargs
        xx, yy = np.mgrid[0:img.shape[0], 0:img.shape[1]]

        # center of mass coordinates
        odimg = trans2od(img)
        com = center_of_mass(odimg)
        xx0 = xx - com[0] - pos[0]
        yy0 = yy - com[1] - pos[1]
        yy0 = np.where(yy0 == 0, 1e-6, yy0)
        rr = np.sqrt(xx0**2 + yy0**2)

        # coordinate projection along fringe axis
        rangle = np.arctan(xx0.astype(float) / yy0)
        rangle = np.where(yy0 > 0, rangle, rangle + np.pi)
        rfringe = rr * np.cos(angle - rangle)

        noise = fitfuncs.gaussian(rr, ampl, size) * np.sin(
            2 * np.pi * rfringe * freq)
        img = img + noise

    return img
Example #8
0
def generate_report(rawframes, transimg, img_name, pixcal, showpdf=True):
    """Generate a report with several image diagnostics

    The report comes in the form of a pdf file that has the name
    ``img_name``.pdf and is put in the same directory as the image.

    **Inputs**

      * rawframes: 3D array, containing the three raw frames
      * transimg: 2D array, containing the transmission image (properly ROIed)
      * img_name: string, the name of the image
      * pixcal: float, pixel size calibration in m/pix.
      * showpdf: bool, if True Acrobat Reader is launched to view the report

    """

    odimg = trans2od(transimg)
    com = center_of_mass(odimg)

    rawfig = show_rawframes(rawframes)
    savefig('trans_rawframes.jpg')
    close()

    ellip = find_ellipticity(transimg)
    ellip_figname = 'ellipfit'

    # figure out how good the ellipticity determination is and create polar plot
    rcoord, rad_profile, rprofiles, angles = radial_interpolate(odimg, com,\
                                    0.3, elliptic=(ellip, 0), full_output=True)
    od_cutoff = find_fitrange(rad_profile)
    av_err = radialprofile_errors(rprofiles, angles, rad_profile, od_cutoff, \
                        showfig=True, savefig_name=ellip_figname, report=False)

    # fit the image
    ToverTF, N, com, ans, rcoord, od_prof, fit_prof = fit_img(transimg, \
            showfig=False, elliptic=(ellip, 0), full_output='odysseus')
    # save the fit figure
    show_fitresult(rcoord, od_prof, fit_prof, ToverTF, N, figname='fitresult')

    # plot the residuals
    show_residuals(rcoord, od_prof, fit_prof, figname='residuals')
    fitresults = (ToverTF[0], N, ans[1], ans[2])

    # fit with several fixed temperatures
    ans_gaussian, ans2, temps = fit_several_fixedT(rcoord, od_prof, od_cutoff,
                                                   ans, ToverTF, pixcal)
    fig = plot_several_temp(rcoord, od_prof, fit_prof, ans, ans_gaussian, ans2,
                            pixcal)
    fig.savefig('several_temps.png')
    close(fig)

    # save a figure zoomed in around the wing of the distribution
    ind = round(ans2[0][2])
    istep = round(1. / (rcoord[1] - rcoord[0])) * 15
    ind = mpl.mlab.find(rcoord > ind).min()
    fig2 = plot_several_temp(rcoord[ind-istep:ind+istep], od_prof[ind-istep:ind+istep], \
                            fit_prof[ind-istep:ind+istep], ans, ans_gaussian,
                            ans2, pixcal)
    fig2.savefig('several_temps_zoomed.png')
    close(fig2)

    # create the report
    write_TeXreport('imgreport', img_name, ellip, ellip_figname, fitresults)
    print 'written TeX'
    pdfname = os.path.splitext(img_name)[0]
    TeX2pdf('imgreport', pdfname)
    print 'written pdf'

    # clean up image files
    pngfiles = ['ellipfit', 'fitresult', 'residuals', 'several_temps', \
                'several_temps_zoomed']
    for pngfile in pngfiles:
        try:
            os.unlink(''.join([pngfile, '.png']))
        except OSError:
            print "file %s.png does not exist, so can't clean it up" % pngfile

    jpgfiles = ['trans_rawframes']
    for jpgfile in jpgfiles:
        try:
            os.unlink(''.join([jpgfile, '.jpg']))
        except OSError:
            print "file %s.jpg does not exist, so can't clean it up" % jpgfile

    if showpdf:
        # launch acrobat reader with the report
        acrocmd = r"acroread %s.pdf" % re.sub(r" ", r"\ ", pdfname)
        acrocmd = re.sub(r";", r"\;", acrocmd)

        if platform.system() == 'Windows':
            os.system(acrocmd)
        else:
            acrocmd = re.sub(r"acroread", r"xdg-open", acrocmd)
            os.system(acrocmd)

    return
Example #9
0
fname = 'NaBEC' #'NaBEC_56ms_tof'
im = Image.open(''.join(['../../archives/2008-04-21/', fname, '.TIF']))
transimg = numpy.asarray(im)
# normalize to background transmission of 1
bg = transimg[0:-20, :]
transimg = transimg/(bg.sum()/bg.size)
od10img = where(transimg>1e-10, -log10(transimg), 10)
pixsize = 20e-6 #20 um/pixel
mag = 2 # magnification
mass_Na = 23*mp
wr = 84 # radial trap freq in Hz
t_tof = 56e-3 # time of flight in seconds

# determine center of mass to use as parameter in fitting of n2D_radial to od10img
com = cmass.center_of_mass(od10img)

def n2D_bose_thermal(r, n0_th, r0_th):
    """Column density for a thermal Bose gas.

    Assume radial symmetry of the cloud, n0_th and r0_th are fit parameters. r
    is a 1d array with values of r with respect to the center of the atom cloud.
    """
    return n0_th/g2(1)*g2(1-r**2/r0_th**2)

def n2D_bose_condensed(r, n0_c, r0_c):
    """Column density for a condensed Bose gas.

    Assume radial symmetry of the cloud, n0_c and r0_c are fit parameters. r
    is a 1d array with values of r with respect to the center of the atom cloud.
    """
Example #10
0
 def test_center_of_mass(self):
     com_ones = center_of_mass(self.ones)
     assert_array_almost_equal(com_ones, (50, 50), decimal=1)
Example #11
0
fname = 'NaBEC'  #'NaBEC_56ms_tof'
im = Image.open(''.join(['../../archives/2008-04-21/', fname, '.TIF']))
transimg = numpy.asarray(im)
# normalize to background transmission of 1
bg = transimg[0:-20, :]
transimg = transimg / (bg.sum() / bg.size)
od10img = where(transimg > 1e-10, -log10(transimg), 10)
pixsize = 20e-6  #20 um/pixel
mag = 2  # magnification
mass_Na = 23 * mp
wr = 84  # radial trap freq in Hz
t_tof = 56e-3  # time of flight in seconds

# determine center of mass to use as parameter in fitting of n2D_radial to od10img
com = cmass.center_of_mass(od10img)


def n2D_bose_thermal(r, n0_th, r0_th):
    """Column density for a thermal Bose gas.

    Assume radial symmetry of the cloud, n0_th and r0_th are fit parameters. r
    is a 1d array with values of r with respect to the center of the atom cloud.
    """
    return n0_th / g2(1) * g2(1 - r**2 / r0_th**2)


def n2D_bose_condensed(r, n0_c, r0_c):
    """Column density for a condensed Bose gas.

    Assume radial symmetry of the cloud, n0_c and r0_c are fit parameters. r