@ -111,6 +111,19 @@ polylog_int = CubicSpline(x_int, poly_tab)
def thermal ( x , x0 , amp , sigma ) :
def thermal ( x , x0 , amp , sigma ) :
""" Calculating thermal density distribution in 1D (scaled such that if amp=1, return = 1)
: param x : axis
: type x : float or 1 d array
: param x0 : position of peak along axis
: type x0 : float
: param amp : amplitude of function
: type amp : float
: param sigma : width of function
: type sigma : float
: return : calculated function value
: rtype : float or 1 D array
"""
res = np . exp ( - 0.5 * ( x - x0 ) * * 2 / sigma * * 2 )
res = np . exp ( - 0.5 * ( x - x0 ) * * 2 / sigma * * 2 )
return amp / 1.643 * polylog_int ( res )
return amp / 1.643 * polylog_int ( res )
@ -363,6 +376,8 @@ class DensityProfileBEC2dModel(lmfit.Model):
prefix = ' ' ,
prefix = ' ' ,
nan_policy = ' raise ' ,
nan_policy = ' raise ' ,
atom_n_conv = 144 ,
atom_n_conv = 144 ,
pre_check = False ,
post_check = False ,
is_debug = False ,
is_debug = False ,
* * kwargs
* * kwargs
) :
) :
@ -370,6 +385,8 @@ class DensityProfileBEC2dModel(lmfit.Model):
' independent_vars ' : independent_vars } )
' independent_vars ' : independent_vars } )
self . atom_n_conv = atom_n_conv
self . atom_n_conv = atom_n_conv
self . pre_check = pre_check
self . post_check = post_check
self . is_debug = is_debug
self . is_debug = is_debug
super ( ) . __init__ ( density_profile_BEC_2d , * * kwargs )
super ( ) . __init__ ( density_profile_BEC_2d , * * kwargs )
self . _set_paramhints_prefix ( )
self . _set_paramhints_prefix ( )
@ -387,48 +404,71 @@ class DensityProfileBEC2dModel(lmfit.Model):
self . set_param_hint ( ' sigma_th ' , min = 0 )
self . set_param_hint ( ' sigma_th ' , min = 0 )
def guess ( self , data , x , y , * * kwargs ) :
"""
Estimate and create initial model parameters for 2 d fit
: param data : Flattened 2 d array , flattened from array with ( x , y ) - - >
: param x :
: param y :
: param kwargs :
: return :
def guess ( self , data , x , y , pre_check = False , post_check = False , * * kwargs ) :
""" Estimate and create initial model parameters for 2d bimodal fit, by doing a 1d bimodal fit along an integrated slice of the image
: param data : Flattened 2 d array , in form [ a_00 , a_10 , a_20 , . . . , a_01 , a_02 , . . , a_XY ] with a_xy , x_dim = X , y_dim = Y
: type data : 1 d numpy array
: param x : flattened X output of np . meshgrid ( x_axis , y_axis ) in form : [ x1 , x2 , . . , xX , x1 , x2 , . . , xX , . . Y times . . ]
: type x : 1 d numpy array
: param y : flattened Y output of np . meshgrid ( x_axis , y_axis ) in form : [ y1 , y1 , . . , y1 ( X times ) , y2 , y2 , . . , y2 ( X times ) , . . Y times . . ]
: type y : 1 d numpy array
: param pre_check : if True the amplitude of the 1 d fit is used to guess if the image is purely BEC or thermal and
the corresponding amplitude of the 2 d fit is set to zero and not varied to speed up the fitting , defaults to False
: type pre_check : bool , optional
: param post_check : if True , after doing a 2 d bimodal fit the number of atoms surrounding the fitted BEC is counted and if the value is
below a certain threshhold the fit is done again with the thermal amplitude set to zero , defaults to False
: type post_check : bool , optional
: return : initial parameters for 2 d fit
: rtype : params object ( lmfit )
"""
"""
#
# global X_guess
# global bval_1d
self . pre_check = pre_check
self . post_check = post_check
# reshaping the image to 2D in the form [[a_00, a_01, .., a_0Y], [a_10,.., a_1Y], .., [a_X0, .., a_XY]], with a_xy
x_width = len ( np . unique ( x ) )
x_width = len ( np . unique ( x ) )
y_width = len ( np . unique ( y ) )
y_width = len ( np . unique ( y ) )
data = np . reshape ( data , ( y_width , x_width ) )
data = np . reshape ( data , ( y_width , x_width ) )
data = data . T
data = data . T
shape = np . shape ( data )
shape = np . shape ( data )
cut_width = np . max ( shape )
if self . is_debug :
print ( f ' shape: {shape} ' )
max_width = np . max ( shape )
thresh = self . calc_thresh ( data )
# binarizing image to guess BEC width and calculate center
thresh = self . calc_thresh ( data , thresh_val = 0.5 )
# calculating center of cloud by statistical distribution of binarized image
center = self . calc_cen ( thresh )
center = self . calc_cen ( thresh )
# guessing BEC width, or better of width of center blob if no BEC is present
BEC_width_guess = self . guess_BEC_width ( thresh , center )
BEC_width_guess = self . guess_BEC_width ( thresh , center )
# plot binarized image and center position for debugging
if self . is_debug :
plt . pcolormesh ( thresh . T , cmap = ' jet ' )
plt . plot ( center [ 0 ] , center [ 1 ] , marker = ' x ' , markersize = 25 , color = ' green ' )
plt . gca ( ) . set_aspect ( ' equal ' )
plt . title ( f ' Binarized image for guessing BEC width + center position (BEC_width: x={BEC_width_guess[0]:.0f}, y={BEC_width_guess[1]:.0f} pix) ' )
plt . xlabel ( ' x_axis ' )
plt . ylabel ( ' y_axis ' )
plt . show ( )
# The 1d fit is done along the short axis of the BEC (decided via the BEC_width guess)
if BEC_width_guess [ 0 ] < BEC_width_guess [ 1 ] :
if BEC_width_guess [ 0 ] < BEC_width_guess [ 1 ] :
if self . is_debug :
if self . is_debug :
print ( f ' x smaller y ' )
print ( f ' x smaller y, 1d fit along x ' )
s_width_ind = 0
s_width_ind = 0
# slice of the image along the short BEC axis with width of BEC width is taken
X_guess = np . sum ( data [ : , round ( center [ 1 ] - BEC_width_guess [ 1 ] / 2 ) : round ( center [ 1 ] + BEC_width_guess [ 1 ] / 2 ) ] , 1 ) / len ( data [ 0 , round ( center [ 1 ] - BEC_width_guess [ 1 ] / 2 ) : round ( center [ 1 ] + BEC_width_guess [ 1 ] / 2 ) ] )
X_guess = np . sum ( data [ : , round ( center [ 1 ] - BEC_width_guess [ 1 ] / 2 ) : round ( center [ 1 ] + BEC_width_guess [ 1 ] / 2 ) ] , 1 ) / len ( data [ 0 , round ( center [ 1 ] - BEC_width_guess [ 1 ] / 2 ) : round ( center [ 1 ] + BEC_width_guess [ 1 ] / 2 ) ] )
else :
else :
if self . is_debug :
if self . is_debug :
print ( f ' y smaller x ' )
print ( f ' y smaller x, 1d fit along y ' )
s_width_ind = 1
s_width_ind = 1
X_guess = np . sum ( data [ round ( center [ 0 ] - BEC_width_guess [ 0 ] / 2 ) : round ( center [ 0 ] + BEC_width_guess [ 0 ] / 2 ) , : ] , 0 ) / len ( data [ 0 , round ( center [ 0 ] - BEC_width_guess [ 0 ] / 2 ) : round ( center [ 0 ] + BEC_width_guess [ 0 ] / 2 ) ] )
X_guess = np . sum ( data [ round ( center [ 0 ] - BEC_width_guess [ 0 ] / 2 ) : round ( center [ 0 ] + BEC_width_guess [ 0 ] / 2 ) , : ] , 0 ) / len ( data [ 0 , round ( center [ 0 ] - BEC_width_guess [ 0 ] / 2 ) : round ( center [ 0 ] + BEC_width_guess [ 0 ] / 2 ) ] )
if self . is_debug :
print ( f ' center = {center} ' )
print ( f ' BEC widths: {BEC_width_guess} ' )
plt . plot ( X_guess )
plt . show ( )
# Creating 1d fit init params + Performing fit
x = np . linspace ( 0 , len ( X_guess ) , len ( X_guess ) )
x = np . linspace ( 0 , len ( X_guess ) , len ( X_guess ) )
max_val = np . max ( X_guess )
max_val = np . max ( X_guess )
@ -436,32 +476,52 @@ class DensityProfileBEC2dModel(lmfit.Model):
fitmodel_1d = lmfit . Model ( density_1d , independent_vars = [ ' x ' ] )
fitmodel_1d = lmfit . Model ( density_1d , independent_vars = [ ' x ' ] )
params_1d = lmfit . Parameters ( )
params_1d = lmfit . Parameters ( )
params_1d . add_many (
params_1d . add_many (
( ' x0_bec ' , center [ s_width_ind ] , True , 0 , 20 0) ,
( ' x0_th ' , center [ s_width_ind ] , True , 0 , 20 0) ,
( ' amp_bec ' , 0.7 * max_val , True , 0 , 1.3 * max_val ) ,
( ' amp_th ' , 0.3 * max_val , True , 0 , 1.3 * max_val ) ,
( ' deltax ' , 3 * BEC_width_guess [ s_width_ind ] , True , 0 , cut _width) ,
( ' x0_bec ' , center [ s_width_ind ] , True , center [ s_width_ind ] - 10 , center [ s_width_ind ] + 1 0 ) ,
( ' x0_th ' , center [ s_width_ind ] , True , center [ s_width_ind ] - 10 , center [ s_width_ind ] + 1 0 ) ,
( ' amp_bec ' , 0.5 * max_val , True , 0 , 1.3 * max_val ) ,
( ' amp_th ' , 0.5 * max_val , True , 0 , 1.3 * max_val ) ,
( ' deltax ' , 3 * BEC_width_guess [ s_width_ind ] , True , 0 , max _width ) ,
# ('sigma_bec',BEC_width_guess[i,j,0]/1.22, True, 0, 50)
# ('sigma_bec',BEC_width_guess[i,j,0]/1.22, True, 0, 50)
( ' sigma_bec ' , BEC_width_guess [ s_width_ind ] / 1.22 , True , 0 , 50 )
( ' sigma_bec ' , BEC_width_guess [ s_width_ind ] / 1.22 , True , 0 , BEC_width_guess [ s_width_ind ] * 2 )
)
)
params_1d . add ( ' sigma_th ' , 3 * BEC_width_guess [ 0 ] , min = 0 , expr = f ' 0.632*sigma_bec + 0.518*deltax ' )
params_1d . add ( ' sigma_th ' , 3 * BEC_width_guess [ 0 ] , min = 0 , expr = f ' 0.632*sigma_bec + 0.518*deltax ' )
res_1d = fitmodel_1d . fit ( X_guess , x = x , params = params_1d )
res_1d = fitmodel_1d . fit ( X_guess , x = x , params = params_1d )
bval_1d = res_1d . best_values
if self . is_debug :
if self . is_debug :
print ( ' ' )
print ( ' 1d fit initialization ' )
print ( f ' center = {center} ' )
print ( f ' BEC widths: {BEC_width_guess} ' )
print ( ' ' )
print ( ' 1d init fit values ' )
params_1d . pretty_print ( )
params_1d . pretty_print ( )
print ( ' 1d fitted values ' )
self . print_bval ( res_1d )
self . print_bval ( res_1d )
x = np . linspace ( 0 , len ( X_guess ) , len ( X_guess ) )
plt . plot ( x , X_guess , label = ' 1d int. data ' )
plt . plot ( x , density_1d ( x , * * bval_1d ) , label = ' bimodal fit ' )
plt . plot ( x , thermal ( x , x0 = bval_1d [ ' x0_th ' ] , amp = bval_1d [ ' amp_th ' ] , sigma = bval_1d [ ' sigma_th ' ] ) , label = ' thermal part ' )
plt . legend ( )
if s_width_ind == 0 :
plt . title ( ' 1d fit of data along x-axis ' )
plt . xlabel ( ' x_axis (pix) ' )
else :
plt . title ( ' 1d fit of data along y-axis ' )
plt . xlabel ( ' y_axis (pix) ' )
plt . show ( )
bval_1d = res_1d . best_values
# scaling amplitudes of 1d fit with the maximum value of blurred 2d data
amp_conv_1d_2d = np . max ( gaussian_filter ( data , sigma = 1 ) ) / ( bval_1d [ ' amp_bec ' ] + bval_1d [ ' amp_th ' ] )
amp_conv_1d_2d = np . max ( gaussian_filter ( data , sigma = 1 ) ) / ( bval_1d [ ' amp_bec ' ] + bval_1d [ ' amp_th ' ] )
max_val = np . max ( data )
max_val = np . max ( data )
params = self . make_params ( )
params = self . make_params ( )
if bval_1d [ ' amp_th ' ] / bval_1d [ ' amp_bec ' ] > 3 :
# if precheck enabled and amp_th is 7x higher than amp_bec (value might be changed), amplitude of BEC in 2d fit is set to zero
if bval_1d [ ' amp_th ' ] / bval_1d [ ' amp_bec ' ] > 7 and self . pre_check :
print ( f ' Image seems to be purely thermal (guessed from 1d fit amplitude) ' )
print ( f ' Image seems to be purely thermal (guessed from 1d fit amplitude) ' )
params [ f ' {self.prefix}amp_bec ' ] . set ( value = 0 , vary = False )
params [ f ' {self.prefix}amp_bec ' ] . set ( value = 0 , vary = False )
@ -472,9 +532,10 @@ class DensityProfileBEC2dModel(lmfit.Model):
params [ f ' {self.prefix}y0_th ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}y0_th ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}sigmax_bec ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigmax_bec ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigmay_bec ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigmay_bec ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = bval_1d [ ' sigma_th ' ] , max = cut _width, vary = True )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = bval_1d [ ' sigma_th ' ] , max = max _width, vary = True )
elif bval_1d [ ' amp_bec ' ] / bval_1d [ ' amp_th ' ] > 10 :
# if precheck enabled and amp_bec is 10x higher than amp_th (value might be changed), amplitude of thermal part in 2d fit is set to zero
elif bval_1d [ ' amp_bec ' ] / bval_1d [ ' amp_th ' ] > 10 and self . pre_check :
print ( ' Image seems to be pure BEC (guessed from 1d fit amplitude) ' )
print ( ' Image seems to be pure BEC (guessed from 1d fit amplitude) ' )
params [ f ' {self.prefix}amp_bec ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_bec ' ] , max = 1.3 * max_val , vary = True )
params [ f ' {self.prefix}amp_bec ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_bec ' ] , max = 1.3 * max_val , vary = True )
@ -494,6 +555,7 @@ class DensityProfileBEC2dModel(lmfit.Model):
else :
else :
print ( ' Error in small width BEC recogintion, s_width_ind should be 0 or 1 ' )
print ( ' Error in small width BEC recogintion, s_width_ind should be 0 or 1 ' )
# params for normal 2d bimodal fit are initialized
else :
else :
params [ f ' {self.prefix}amp_bec ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_bec ' ] , max = 1.3 * max_val , vary = True )
params [ f ' {self.prefix}amp_bec ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_bec ' ] , max = 1.3 * max_val , vary = True )
params [ f ' {self.prefix}amp_th ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_th ' ] , max = 1.3 * max_val , vary = True )
params [ f ' {self.prefix}amp_th ' ] . set ( value = amp_conv_1d_2d * bval_1d [ ' amp_th ' ] , max = 1.3 * max_val , vary = True )
@ -501,7 +563,7 @@ class DensityProfileBEC2dModel(lmfit.Model):
params [ f ' {self.prefix}y0_bec ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}y0_bec ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}x0_th ' ] . set ( value = center [ 0 ] , min = center [ 0 ] - 10 , max = center [ 0 ] + 10 , vary = True )
params [ f ' {self.prefix}x0_th ' ] . set ( value = center [ 0 ] , min = center [ 0 ] - 10 , max = center [ 0 ] + 10 , vary = True )
params [ f ' {self.prefix}y0_th ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}y0_th ' ] . set ( value = center [ 1 ] , min = center [ 1 ] - 10 , max = center [ 1 ] + 10 , vary = True )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = bval_1d [ ' sigma_th ' ] , max = cut _width, vary = True )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = bval_1d [ ' sigma_th ' ] , max = max _width, vary = True )
if s_width_ind == 0 :
if s_width_ind == 0 :
params [ f ' {self.prefix}sigmax_bec ' ] . set ( value = bval_1d [ ' sigma_bec ' ] , max = 2 * BEC_width_guess [ 0 ] , vary = True )
params [ f ' {self.prefix}sigmax_bec ' ] . set ( value = bval_1d [ ' sigma_bec ' ] , max = 2 * BEC_width_guess [ 0 ] , vary = True )
@ -516,33 +578,43 @@ class DensityProfileBEC2dModel(lmfit.Model):
print ( ' ' )
print ( ' ' )
print ( ' Init Params ' )
print ( ' Init Params ' )
params . pretty_print ( )
params . pretty_print ( )
print ( ' ' )
return lmfit . models . update_param_vals ( params , self . prefix , * * kwargs )
return lmfit . models . update_param_vals ( params , self . prefix , * * kwargs )
def fit ( self , data , * * kwargs ) :
def fit ( self , data , * * kwargs ) :
""" fitting function overwrites parent class fitting function of lmfit, in order to check (if post_check is enabled)
if thermal fit completely lies in BEC fit by counting sourrounding number of atoms and comparing it to threshold value
data_1d = data
: param data : Flattened 2 d array , in form [ a_00 , a_10 , a_20 , . . . , a_01 , a_02 , . . , a_XY ] with a_xy , x_dim = X , y_dim = Y
: type data : 1 d numpy array
: return : result of 2 d fit
: rtype : result object ( lmfit )
"""
res = super ( ) . fit ( data_1d , * * kwargs )
res = super ( ) . fit ( data , * * kwargs )
if self . is_debug :
if self . is_debug :
print ( ' bval first fit ' )
print ( ' bval first fit ' )
self . print_bval ( res )
self . print_bval ( res )
if res . params [ ' amp_bec ' ] . vary and res . params [ ' amp_th ' ] . vary :
bval = res . best_values
bval = res . best_values
# Do described post_check if enabled
if res . params [ ' amp_bec ' ] . vary and res . params [ ' amp_th ' ] . vary and bval [ ' amp_bec ' ] > 0.5 * bval [ ' amp_th ' ] and self . post_check :
# creating image by cutting out region around BEC and counting number of atoms
sigma_cut = max ( bval [ ' sigmay_bec ' ] , bval [ ' sigmax_bec ' ] )
sigma_cut = max ( bval [ ' sigmay_bec ' ] , bval [ ' sigmax_bec ' ] )
tf_fit = ThomasFermi_2d ( kwargs [ ' x ' ] , kwargs [ ' y ' ] , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
tf_fit = ThomasFermi_2d ( kwargs [ ' x ' ] , kwargs [ ' y ' ] , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
tf_fit_2 = ThomasFermi_2d ( kwargs [ ' x ' ] , kwargs [ ' y ' ] , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = 1.5 * sigma_cut , sigmay = 1.5 * sigma_cut )
tf_fit_2 = ThomasFermi_2d ( kwargs [ ' x ' ] , kwargs [ ' y ' ] , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = 1.5 * sigma_cut , sigmay = 1.5 * sigma_cut )
mask = np . where ( tf_fit > 0 , np . nan , data_1d )
#mask[i,j] = gaussian_filter(mask[i,j], sigma = 0.4)
mask = np . where ( tf_fit > 0 , np . nan , data )
mask = np . where ( tf_fit_2 > 0 , mask , np . nan )
mask = np . where ( tf_fit_2 > 0 , mask , np . nan )
N_c = np . nansum ( mask )
N_c = np . nansum ( mask )
# conversion N_count to Pixels
# conversion N_count to Pixels
N_a = self . atom_n_conv * N_c
N_a = self . atom_n_conv * N_c
#TODO change fixed threshhold to variable
# If number of atoms around BEC is small the image is guessed to be purely BEC and another 2d fit is performed with setting the thermal amplitude to zero
if N_a < 6615 :
if N_a < 6615 :
print ( ' No thermal part detected, performing fit without thermal function ' )
print ( ' No thermal part detected, performing fit without thermal function ' )
params = res . params
params = res . params
@ -551,7 +623,7 @@ class DensityProfileBEC2dModel(lmfit.Model):
params [ f ' {self.prefix}y0_th ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}y0_th ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = 1 , vary = False )
params [ f ' {self.prefix}sigma_th ' ] . set ( value = 1 , vary = False )
res = super ( ) . fit ( data_1d , x = kwargs [ ' x ' ] , y = kwargs [ ' y ' ] , params = params )
res = super ( ) . fit ( data , x = kwargs [ ' x ' ] , y = kwargs [ ' y ' ] , params = params )
return res
return res
@ -560,49 +632,38 @@ class DensityProfileBEC2dModel(lmfit.Model):
def calc_thresh ( self , data , thresh_val = 0.3 , sigma = 0.4 ) :
def calc_thresh ( self , data , thresh_val = 0.3 , sigma = 0.4 ) :
""" Returns thresholded binary image after blurring to guess BEC size
""" Returns thresholded binary image after blurring to guess BEC size
: param data : 2 d image or 1 D or 2 D array containing 2 d images
: type data : 2 d , 3 d or 4 d numpy array
: param data : 2 d image
: type data : 2 d numpy array
: param thresh_val : relative threshhold value for binarization with respect to maximum of blurred image
: param thresh_val : relative threshhold value for binarization with respect to maximum of blurred image
: param sigma : sigma of gaussian blur filter ( see scipy . ndimage . gaussian_filter
: return : binary 2 d image or 1 D or 2 D array containing 2 d images
: rtype : 2 d , 3 d or 4 d numpy array
: param sigma : sigma of gaussian blur filter ( see scipy . ndimage . gaussian_filter )
: return : binary 2 d image
: rtype : 2 d numpy array
"""
"""
shape = np . shape ( data )
shape = np . shape ( data )
thresh = np . zeros ( shape )
thresh = np . zeros ( shape )
blurred = gaussian_filter ( data , sigma = sigma )
blurred = gaussian_filter ( data , sigma = sigma )
if len ( shape ) == 4 :
for i in range ( 0 , shape [ 0 ] ) :
for j in range ( 0 , shape [ 1 ] ) :
thresh [ i , j ] = np . where ( blurred [ i , j ] < np . max ( blurred [ i , j ] ) * thresh_val , 0 , 1 )
elif len ( shape ) == 3 :
for i in range ( 0 , shape [ 0 ] ) :
thresh [ i ] = np . where ( blurred [ i ] < np . max ( blurred [ i ] ) * thresh_val , 0 , 1 )
elif len ( shape ) == 2 :
thresh = np . where ( blurred < np . max ( blurred ) * thresh_val , 0 , 1 )
thresh = np . where ( blurred < np . max ( blurred ) * thresh_val , 0 , 1 )
else :
print ( " Shape of data is wrong, output is empty " )
return thresh
return thresh
def calc_cen ( self , thresh1 ) :
def calc_cen ( self , thresh1 ) :
"""
returns array : [ X_center , Y_center ]
""" Calculating the center of a blob (atom cloud) in a binarized image by first calculating the probability distribution along both axes and afterwards the expectation value
: param thresh1 : Binary 2 D image in the form [ [ a_00 , a_01 , . . , a_0Y ] , [ a_10 , . . , a_1Y ] , . . , [ a_X0 , . . , a_XY ] ] , with a_xy , x_dim = X , y_dim = Y
: type thresh1 : 2 D numpy array
: return : center coordinates of blob in form [ x_center , y_center ]
: rtype : 1 d numpy array ( shape = ( 1 , 2 ) )
"""
"""
cen = np . zeros ( 2 )
cen = np . zeros ( 2 )
( Y , X ) = np . shape ( thresh1 )
( X , Y ) = np . shape ( thresh1 )
thresh1 = thresh1 / np . sum ( thresh1 )
thresh1 = thresh1 / np . sum ( thresh1 )
# marginal distributions
# marginal distributions
dx = np . sum ( thresh1 , 0 )
dy = np . sum ( thresh1 , 1 )
dx = np . sum ( thresh1 , 1 )
dy = np . sum ( thresh1 , 0 )
# expected values
# expected values
cen [ 0 ] = np . sum ( dx * np . arange ( X ) )
cen [ 0 ] = np . sum ( dx * np . arange ( X ) )
@ -610,42 +671,61 @@ class DensityProfileBEC2dModel(lmfit.Model):
return cen
return cen
def guess_BEC_width ( self , thresh , center ) :
def guess_BEC_width ( self , thresh , center ) :
"""
returns width of thresholded area along both axis through the center with shape of thresh and [ X_width , Y_width ] for each image
""" returns width of blob in binarized image along both axis through the center
: param thresh : Binary 2 D image in the form [ [ a_00 , a_01 , . . , a_0Y ] , [ a_10 , . . , a_1Y ] , . . , [ a_X0 , . . , a_XY ] ] , with a_xy , x_dim = X , y_dim = Y
: type thresh : 2 d numpy array
: param center : center of blob in image in form [ x_center , y_center ]
: type center : 1 d numpy array ( shape = ( 1 , 2 ) )
: return : width of blob in image as [ x_width , y_width ]
: rtype : 1 d numpy array ( shape = ( 1 , 2 ) )
"""
"""
shape = np . shape ( thresh )
shape = np . shape ( thresh )
if len ( shape ) == 2 :
if len ( shape ) == 2 :
BEC_width_guess = np . array ( [ np . sum ( thresh [ round ( center [ 1 ] ) , : ] ) , np . sum ( thresh [ : , round ( center [ 0 ] ) ] ) ] )
elif len ( shape ) == 3 :
BEC_width_guess = np . zeros ( ( shape [ 0 ] , 2 ) )
for i in range ( 0 , shape [ 0 ] ) :
BEC_width_guess [ i , 0 ] = np . sum ( thresh [ i , round ( center [ i , j , 1 ] ) , : ] )
BEC_width_guess [ i , 1 ] = np . sum ( thresh [ i , : , round ( center [ i , j , 0 ] ) ] )
elif len ( shape ) == 4 :
BEC_width_guess = np . zeros ( ( shape [ 0 ] , shape [ 1 ] , 2 ) )
for i in range ( 0 , shape [ 0 ] ) :
for j in range ( 0 , shape [ 1 ] ) :
BEC_width_guess [ i , j , 0 ] = np . sum ( thresh [ i , j , round ( center [ i , j , 1 ] ) , : ] )
BEC_width_guess [ i , j , 1 ] = np . sum ( thresh [ i , j , : , round ( center [ i , j , 0 ] ) ] )
BEC_width_guess = np . array ( [ np . sum ( thresh [ : , round ( center [ 1 ] ) ] ) , np . sum ( thresh [ round ( center [ 0 ] ) , : ] ) ] )
for i in range ( 2 ) :
if BEC_width_guess [ i ] < = 0 :
BEC_width_guess [ i ] = 1
else :
else :
print ( " Shape of data is wrong, output is empty " )
print ( " Shape of data is wrong, output is empty " )
return BEC_width_guess
return BEC_width_guess
def cond_frac ( self , results ) :
""" Returns condensate fraction """
def cond_frac ( self , results , X , Y ) :
""" Returns condensate fraction of 2d fitting result
: param results : result of 2 d bimodal fit
: type results : result object ( lmfit )
: param X : X output of np . meshgrid ( x_axis , y_axis ) in form : [ [ x1 , x2 , . . , xX ] , [ x1 , x2 , . . , xX ] . . Y times . . ]
: type X : 2 d numpy array
: param Y : Y output of np . meshgrid ( x_axis , y_axis ) in form : [ [ y1 , y1 , . . , y1 ( X times ) ] , [ y2 , y2 , . . , y2 ( X times ) ] , . . Y times . . ]
: type Y : 2 d numpy array
: return : condensate fraction
: rtype : float between 0 and 1
"""
bval = results . best_values
bval = results . best_values
tf_fit = ThomasFermi_2d ( X , Y , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
tf_fit = ThomasFermi_2d ( X , Y , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
N_bec = np . sum ( tf_fit )
N_bec = np . sum ( tf_fit )
fit = density_profile_BEC_2d ( X , Y , * * bval )
fit = density_profile_BEC_2d ( X , Y , * * bval )
N_ges = np . sum ( fit )
N_ges = np . sum ( fit )
return N_bec / N_ges
return N_bec / N_ges
def return_atom_number ( self , result , X , Y , is_print = True ) :
def return_atom_number ( self , result , X , Y , is_print = True ) :
""" Printing fitted atom number in bec + thermal state """
""" Calculating (and printing if enabled) fitted atom number in BEC + thermal state, and condensate fraction
: param result : result of 2 d bimodal fit
: type result : result object ( lmfit )
: param X : X output of np . meshgrid ( x_axis , y_axis ) in form : [ [ x1 , x2 , . . , xX ] , [ x1 , x2 , . . , xX ] . . Y times . . ]
: type X : 2 d numpy array
: param Y : Y output of np . meshgrid ( x_axis , y_axis ) in form : [ [ y1 , y1 , . . , y1 ( X times ) ] , [ y2 , y2 , . . , y2 ( X times ) ] , . . Y times . . ]
: type Y : 2 d numpy array
: param is_print : if true results are printed , defaults to True
: type is_print : bool , optional
: return : dictionary with total atom number N , BEC N_bec , thermal N_th and condensate fraction cond_f
: rtype : dictionary
"""
bval = result . best_values
bval = result . best_values
tf_fit = ThomasFermi_2d ( X , Y , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
tf_fit = ThomasFermi_2d ( X , Y , centerx = bval [ ' x0_bec ' ] , centery = bval [ ' y0_bec ' ] , amplitude = bval [ ' amp_bec ' ] , sigmax = bval [ ' sigmax_bec ' ] , sigmay = bval [ ' sigmay_bec ' ] )
N_bec = self . atom_n_conv * np . sum ( tf_fit )
N_bec = self . atom_n_conv * np . sum ( tf_fit )
@ -653,6 +733,8 @@ class DensityProfileBEC2dModel(lmfit.Model):
th_fit = polylog2_2d ( X , Y , centerx = bval [ ' x0_th ' ] , centery = bval [ ' y0_th ' ] , amplitude = bval [ ' amp_th ' ] , sigmax = bval [ ' sigma_th ' ] , sigmay = bval [ ' sigma_th ' ] )
th_fit = polylog2_2d ( X , Y , centerx = bval [ ' x0_th ' ] , centery = bval [ ' y0_th ' ] , amplitude = bval [ ' amp_th ' ] , sigmax = bval [ ' sigma_th ' ] , sigmay = bval [ ' sigma_th ' ] )
N_th = self . atom_n_conv * np . sum ( th_fit )
N_th = self . atom_n_conv * np . sum ( th_fit )
N = N_bec + N_th
frac = N_bec / N
# fit = density_profile_BEC_2d(X,Y, **bval)
# fit = density_profile_BEC_2d(X,Y, **bval)
# N_ges = self.atom_n_conv * np.sum(fit)
# N_ges = self.atom_n_conv * np.sum(fit)
@ -661,22 +743,47 @@ class DensityProfileBEC2dModel(lmfit.Model):
print ( ' Atom numbers: ' )
print ( ' Atom numbers: ' )
print ( f ' N_bec: {N_bec :.0f} ' )
print ( f ' N_bec: {N_bec :.0f} ' )
print ( f ' N_th: {N_th :.0f} ' )
print ( f ' N_th: {N_th :.0f} ' )
print ( f ' N_ges: {N_bec + N_th :.0f} ' )
print ( f ' Cond. frac: {N_bec/(N_bec + N_th):.2f} ' )
print ( f ' N_ges: {N:.0f} ' )
print ( f ' Cond. frac: {frac *1e2:.2f} % ' )
print ( ' ' )
print ( ' ' )
atom_n = { ' N ' : N , ' N_bec ' : N_bec , ' N_th ' : N_th , ' cond_f ' : frac }
return atom_n
def return_temperature ( self , result , tof , omg = None , is_print = True , eff_pix = 2.472e-6 ) :
""" Returns temperature of thermal cloud
def return_temperature ( self , result , omg , tof , is_print = True , eff_pix = 2.472e-6 ) :
""" Returns temperature of thermal cloud """
: param result : result of 2 d bimodal fit
: type result : result object ( lmfit )
: param tof : time of flight
: type tof : float
: param omg : geometric average of trapping frequencies , defaults to None
: type omg : float , if NONE initial cloud size is neglected optional
: param is_print : if True temperature is printed , defaults to True
: type is_print : bool , optional
: param eff_pix : effective pixel size of imaging setup , defaults to 2.472e-6
: type eff_pix : float , optional
: return : temperature of atom cloud
: rtype : float
"""
R_th = result . best_values [ ' sigma_th ' ] * eff_pix * np . sqrt ( 2 )
R_th = result . best_values [ ' sigma_th ' ] * eff_pix * np . sqrt ( 2 )
print ( R_th )
# print(R_th)
if omg is None :
T = R_th * * 2 * 164 * const . u / const . k * ( tof * * 2 ) * * ( - 1 )
else :
T = R_th * * 2 * 164 * const . u / const . k * ( 1 / omg * * 2 + tof * * 2 ) * * ( - 1 )
T = R_th * * 2 * 164 * const . u / const . k * ( 1 / omg * * 2 + tof * * 2 ) * * ( - 1 )
if is_print :
if is_print :
print ( f ' Temperature: {T*1e9:.2f} nK ' )
print ( f ' Temperature: {T*1e9:.2f} nK ' )
return T
return T
def print_bval ( self , res_s ) :
def print_bval ( self , res_s ) :
""" nicely print best fitted values + init values + bounds """
""" nicely print best fitted values + init values + bounds
: param res_s : result of 2 d bimodal fit
: type res_s : result object ( lmfit )
"""
keys = res_s . best_values . keys ( )
keys = res_s . best_values . keys ( )
bval = res_s . best_values
bval = res_s . best_values
init = res_s . init_params
init = res_s . init_params