- Add load - Add compress - Add big_to_small - Add small_to_big - Add check_side - Add fill
119 lines
5.2 KiB
Python
119 lines
5.2 KiB
Python
from astropy.io.fits import open
|
|
from numpy import compress as numpy_compress
|
|
from numpy import ndarray
|
|
|
|
def load( filename ):
|
|
"""
|
|
retrieve data from naroo fits
|
|
"""
|
|
if not isinstance( filename , str ):
|
|
raise ValueError( 'the filename must be a string, ' + type( filename ) + ' given' )
|
|
|
|
hdul = open( filename )
|
|
data = hdul[0].data
|
|
hdul.close()
|
|
|
|
return data
|
|
|
|
def compress( data , factor ):
|
|
"""
|
|
divide the size of the data by 2**factor
|
|
"""
|
|
if not isinstance( data , ndarray ) and not isinstance( data , list ):
|
|
raise ValueError( 'data must be a list, ' + type( data ) + ' given' )
|
|
if not isinstance( factor , int ):
|
|
raise ValueError( 'factor must be an integer, ' + type( factor ) + ' given' )
|
|
|
|
for _ in range( factor ):
|
|
data = numpy_compress( [ True , False ] * ( data.shape[1] // 2 ) , data , axis = 1 )
|
|
data = numpy_compress( [ True , False ] * ( data.shape[0] // 2 ) , data , axis = 0 )
|
|
|
|
return data
|
|
|
|
def big_to_small( indexes , factor ):
|
|
"""
|
|
convert a coordinate of a point in the non compressed data to the same coordinate
|
|
in the compressed one (there is a loss of information here !)
|
|
"""
|
|
if not isinstance( indexes , int ) and not isinstance( indexes , list ) and not isinstance( indexes , tuple ):
|
|
raise ValueError( 'indexes must be an integer or a tuple, ' + type( indexes ) + ' given' )
|
|
if not isinstance( factor , int ):
|
|
raise ValueError( 'factor mus be an integer' )
|
|
|
|
if isinstance( indexes , int ):
|
|
return big_to_small( [ indexes ] , factor )[0]
|
|
if isinstance( indexes , tuple ):
|
|
return tuple( big_to_small( list( indexes ) , factor ) )
|
|
|
|
for i in range( len( indexes ) ):
|
|
indexes[i] = indexes[i] // ( 2 ** factor )
|
|
|
|
return indexes
|
|
|
|
def small_to_big( indexes , factor ):
|
|
"""
|
|
convert a coordinate of a point n the compressed data to the same coordinate
|
|
in the compressed one
|
|
"""
|
|
if not isinstance( indexes , int ) and not isinstance( indexes , list ) and not isinstance( indexes , tuple ):
|
|
raise ValueError( 'indexes must be an integer or a tuple, ' + type( indexes ) + ' given' )
|
|
if not isinstance( factor , int ):
|
|
raise ValueError( 'factor mus be an integer' )
|
|
|
|
if isinstance( indexes , int ):
|
|
return small_to_big( [ indexes ] , factor )[0]
|
|
if isinstance( indexes , tuple ):
|
|
return tuple( small_to_big( list( indexes ) , factor ) )
|
|
|
|
for i in range( len( indexes ) ):
|
|
indexes[i] = int( indexes[i] * 2 ** factor )
|
|
|
|
return indexes
|
|
|
|
def check_side( data , point , tolerance ):
|
|
"""
|
|
give coordinates of all side point of the given point which have an
|
|
intensity difference inferior than tolerance
|
|
"""
|
|
if not isinstance( data , ndarray ) and not isinstance( data , list ):
|
|
raise ValueError( 'data must be a list, ' + type( data ) + ' given' )
|
|
if not isinstance( point , ndarray ) and not isinstance( point , tuple ) and not isinstance( point , list ):
|
|
raise ValueError( 'point must be a tuple, ' + type( point ) + ' given' )
|
|
if not isinstance( tolerance , int ) and not isinstance( tolerance , float ):
|
|
raise ValueError( 'tolerance must be a number, ' + type( tolerance ) + ' given' )
|
|
|
|
positions , intensity = [] , data[ point ]
|
|
if 0 <= position[0] < data.shape[0] - 1 and intensity - tolerance <= data[ position[0] + 1 , position[1] ] <= intensity + tolerance:
|
|
positions.append( ( position[0] + 1 , position[1] ) )
|
|
if 0 < position[0] < data.shape[0] and intensity - tolerance <= data[ position[0] - 1 , position[1] ] <= intensity + tolerance:
|
|
positions.append( ( position[0] - 1 , position[1] ) )
|
|
if 0 <= position[1] < data.shape[1] - 1 and intensity - tolerance <= data[ position[0] , position[1] + 1 ] <= intensity + tolerance:
|
|
positions.append( ( position[0] , position[1] + 1 ) )
|
|
if 0 < position[1] < data.shape[1] and intensity - tolerance <= data[ position[0] , position[1] - 1 ] <= intensity + tolerance:
|
|
positions.append( ( position[0] , position[1] - 1 ) )
|
|
return positions
|
|
|
|
def fill( data , point , tolerance , limit = 100000 ):
|
|
"""
|
|
give the coordinate of all points that fill the area with the given tolerance
|
|
"""
|
|
if not isinstance( data , ndarray ) and not isinstance( data , list ):
|
|
raise ValueError( 'data must be a list, ' + type( data ) + ' given' )
|
|
if not isinstance( point , ndarray ) and not isinstance( point , tuple ) and not isinstance( point , list ):
|
|
raise ValueError( 'point must be a tuple, ' + type( point ) + ' given' )
|
|
if not isinstance( tolerance , int ) and not isinstance( tolerance , float ):
|
|
raise ValueError( 'tolerance must be a number, ' + type( tolerance ) + ' given' )
|
|
if not isinstance( limit , int ):
|
|
raise ValueError( 'limit must be an integer, ' + type( limit ) + ' given' )
|
|
|
|
taken_point = []
|
|
new_points = [ point ]
|
|
i = 0
|
|
while len( new_points ) != 0 and i < limit:
|
|
point = new_points.pop(0)
|
|
taken_point.append( point )
|
|
for position in check_side( data , point , tolerance ):
|
|
if not position in new_points and not position in taken_point:
|
|
new_points.append( position )
|
|
i += 1
|
|
return np.array( taken_point )
|