Commit 84bc3e67 authored by Caillat Michel's avatar Caillat Michel
Browse files

Introduced the contours

parent d0bff4fd
......@@ -38,7 +38,7 @@ class DataBlock:
# What is the PNG files root directory
__PNGFilePrefix = ""
# What is the PNG files root directory
__OBJFilePrefix = ""
......@@ -98,7 +98,7 @@ class DataBlock:
@classmethod
def setPNGFilePrefix(cls, PNGFilePrefix):
DataBlock.__PNGFilePrefix = PNGFilePrefix
@classmethod
def setOBJFilePrefix(cls, OBJFilePrefix):
DataBlock.__OBJFilePrefix = OBJFilePrefix
......@@ -110,7 +110,7 @@ class DataBlock:
@classmethod
def getPNGFilePrefix(cls):
return DataBlock.__PNGFilePrefix
@classmethod
def getOBJFilePrefix(cls):
return DataBlock.__OBJFilePrefix
......@@ -697,8 +697,40 @@ class DataBlock:
def getSlice(self, iFREQ, step=1):
self.__logger.debug("getSlice: entering")
x = None
numDimensions = len(self.__data.shape)
if numDimensions == 2:
x = self.__data[0:self.__data.shape[0]:step, 0:self.__data.shape[1]:step]
elif numDimensions == 3:
if iFREQ == None:
iFREQ = self.__data.shape[0] / 2
x = self.__data[iFREQ, 0:self.__data.shape[1]:step, 0:self.__data.shape[2]:step]
self.__logger.debug("getSlice: exiting")
return x
def __getSlice(self, iFREQ, step=1):
self.__logger.debug("getSlice: entering")
x = None
numDimensions = len(self.__data.shape)
if numDimensions == 2:
x = self.__data[0:self.__data.shape[0]:step, 0:self.__data.shape[1]:step]
elif numDimensions == 3:
if iFREQ == None:
iFREQ = self.__data.shape[0] / 2
x = self.__data[iFREQ, 0:self.__data.shape[1]:step, 0:self.__data.shape[2]:step]
self.__logger.debug("getSlice: exiting")
return x
def getSlice(self, iFREQ, step=1):
self.__logger.debug("getSlice: entering")
result = dict()
numDimensions = len(self.__data.shape)
try :
if numDimensions > 3 or numDimensions < 2:
......@@ -706,11 +738,7 @@ class DataBlock:
result["status"]=False
result["message"]= message
else:
x = None
if numDimensions == 2:
x = self.__data[0:self.__data.shape[0]:step, 0:self.__data.shape[1]:step]
elif numDimensions == 3:
x = self.__data[iFREQ, 0:self.__data.shape[1]:step, 0:self.__data.shape[2]:step]
x = self.__getSlice(iFREQ, step)
self.__logger.debug(f"type self.__data = {type(self.__data)}, type x = {type(x)}")
self.__logger.debug("Avant isnan")
self.__logger.debug(x.shape)
......@@ -1028,6 +1056,54 @@ class DataBlock:
self.__logger.debug("getDataBlockInfos: exiting")
return result
def getContours(self, iFREQ=None, iDEC0=None, iDEC1=None, iRA0=None, iRA1=None, **kwargs) :
self.__logger.debug("getContours: entering")
# Determine the limits
numDims = len(self.__data.shape)
iDEC0 = iDEC0 if iDEC0 else 0
iDEC1 = iDEC1 if iDEC1 else (self.__data.shape[1] if numDims > 2 else self.__data.shape[0])
iRA0 = iRA0 if iRA0 else 0
iRA1 = iRA1 if iRA1 else (self.__data.shape[2] if numDims > 2 else self.__data.shape[1])
levels = None
quantiles = [0.99]
for key, value in kwargs.items():
if key == 'levels':
levels = value
elif key == 'quantiles':
quantiles = value
self.__logger.debug("levels = %r, quantiles = %r" % (levels, quantiles))
# Get the data to be contoured
slice = self.__getSlice(iFREQ)[iDEC0:iDEC1, iRA0:iRA1]
self.__logger.debug("slice shape %r", slice.shape)
#self.__logger.debug("%r,%r" % (da.min(slice[!da.isnan(slice)]).compute(), da.max(slice[!da.isnan(slice)]).compute()))
# Determine the contours levels.
if not levels:
levels = [np.quantile(slice[~da.isnan(slice)].compute(), quantiles[0])]
self.__logger.debug('levels %r' % levels)
# Produce the contours.
fig, ax = pp.subplots()
CS = ax.contour(np.arange(slice.shape[1]), np.arange(slice.shape[0]), slice, levels)
features = []
for set in CS.allsegs:
for c in set :
feature = {"type":"LineString", "coordinates": [[round(x[0]), round(x[1])] for x in c.tolist()]}
features.append(feature)
contours_geojson = { "type": "FeatureCollection", "features" : features }
result = {"status" : True, "message" : "", "result": contours_geojson}
self.__logger.debug("getContours: exiting")
return result
#
# End of DataBlock class definition.
#
......@@ -252,6 +252,15 @@ class DataManagerImpl :
self.__logger.debug("getSummedSliceRangeAsPNG : exiting.")
return result
def getContours(self, relFITSFilePath, iFREQ, iDEC0, iDEC1, iRA0, iRA1, **kwargs):
self.__logger.debug("getContours : entering.")
result = self.__checkPresence(relFITSFilePath)
self.__logger.debug("kwargs = %r" % kwargs)
if result :
result = self.__dataBlocks[relFITSFilePath].getContours(iFREQ, iDEC0, iDEC1, iRA0, iRA1, **kwargs)
self.__logger.debug("getContours : exiting.")
return result
#
# create fits file containing a spectrum at iRA, iDEC
# The use case is interoperability via SAMP
......@@ -359,7 +368,7 @@ class DataManagerImpl :
del self.__dataBlocks[db]
self.__logger.debug("purgeDataBlocks : exiting")
return {"status": True, "message": f"{len(tobePurged)} data set(s) erased.", "result": tobePurged}
#
#
#
......@@ -367,7 +376,7 @@ class DataManagerImpl :
self.__logger.debug("ytObj : entering")
name = "Abell1795.CO.image.pbcor"
filename = FITSFilePrefix+"Abell1795.CO.image.pbcor.fits"
fileout = OBJFilePrefix+"Abell1795.CO.image.pbcor"
fileout = OBJFilePrefix+"Abell1795.CO.image.pbcor"
#create cube by extracting data from the fits
cube= fits.getdata(filename)
cube = cube.squeeze()
......@@ -375,7 +384,7 @@ class DataManagerImpl :
cube.shape
Nsigma = 0.1
#define the delimeter
reduce=0.4 # 20% of the nb of x and y channels (to avoid the edge noise)
schrink = 1 # velocity axis: new v-axis size is RA/DEC-axis size / schrink
......@@ -406,7 +415,7 @@ class DataManagerImpl :
surf.export_obj(fileout)
self.__logger.debug("ytObj : exiting")
return {"status": True, "message": "", "result": name}
#
#
# End of the DataManagerImpl class
......
......@@ -814,6 +814,43 @@ def getSummedSliceRangeAsPNG():
return json.dumps(result)
@route( baseUrl+'/getContours', name='getContours', method='POST')
@enable_cors
def getContours():
logger.debug("getContours - wrapper : entering")
try:
body = byteify(json.loads(request.body.read()))
relFITSFilePath = rebuildFilename(body['relFITSFilePath'])
optParams = json.loads(body["optParams"])
iFREQ = getIntValue(optParams['iFREQ']) if 'iFREQ' in optParams else None
iDEC0 = getIntValue(optParams['iDEC0']) if 'iDEC0' in optParams else None
iDEC1 = getIntValue(optParams['iDEC1']) if 'iDEC1' in optParams else None
iRA0 = getIntValue(optParams['iRA0']) if 'iRA0' in optParams else None
iRA1 = getIntValue(optParams['iRA1']) if 'iRA1' in optParams else None
kwargs = {}
if 'levels' in optParams:
levels = [getFloatValue(level) for level in optParams['levels']]
kwargs['levels'] = levels
if 'quantiles' in optParams:
quantiles = [getFloatValue(level) for level in optParams['quantiles']]
kwargs['quantiles'] = quantiles
logger.debug("kwargs = %r" % kwargs)
result = dm.getContours(relFITSFilePath, iFREQ, iDEC0, iDEC1, iRA0, iRA1, **kwargs)
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
message = "%s ! %s" % (type(e), "".join(traceback.format_list(traceback.extract_tb(exc_traceback))))
logger.debug(message)
result = {"status": False, "message": message}
response.content_type = "application/json; charset=utf-8"
logger.debug("getContours - wrapper : exiting")
return json.dumps(result)
"""
Given the values of a spectrum 'ydata' passed with the corresponding frequency values 'xdata'
at an (x,y) given position ( integer indexes ) in the RAxDEC plan of a cube, generate a FITS file containing that
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment