From 7b1e8940c92abd4324d0672e19a1f466d48a5975 Mon Sep 17 00:00:00 2001 From: linarphy Date: Thu, 4 May 2023 16:46:35 +0200 Subject: [PATCH] Add first utils functions - Add load - Add compress - Add big_to_small - Add small_to_big - Add check_side - Add fill --- utils.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 utils.py diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..3399368 --- /dev/null +++ b/utils.py @@ -0,0 +1,119 @@ +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 )