diff --git a/README.md b/README.md index 95f34f4..5a6e0f5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![version](https://img.shields.io/badge/version-1.3-blue) +![version](https://img.shields.io/badge/version-1.4-blue) ![pythonversion](https://img.shields.io/badge/Python-3.7-blue) ![idlversion](https://img.shields.io/badge/IDL-8.3-blue) diff --git a/docs/doc.md b/docs/doc.md index 79483d4..e4fac66 100644 --- a/docs/doc.md +++ b/docs/doc.md @@ -41,6 +41,10 @@ Using IDL routines containing in omegapy/omega_routines/*. `get_omega_py_path()` +`get_names(omega_list)` + +`get_ls(omega_list)` + `update_cube_quality(obs_name='ORB*.pkl', folder='auto', version=Version, base_folder=_omega_py_path)` diff --git a/docs/doc_omega_data.md b/docs/doc_omega_data.md index 70c51e4..79eaf14 100644 --- a/docs/doc_omega_data.md +++ b/docs/doc_omega_data.md @@ -41,6 +41,10 @@ Using IDL routines containing in omegapy/omega_routines/*. `get_omega_py_path()` +`get_names(omega_list)` + +`get_ls(omega_list)` + `update_cube_quality(obs_name='ORB*.pkl', folder='auto', version=_Version, base_folder=_omega_py_path)` @@ -97,6 +101,19 @@ class omegapy.omega_data.OMEGAdata(obs='', empty=False, data_path=_omega_bin_pat The longitude grid of the observation (from the edge of the pixels). surf_temp : 2D array The retrieved surface temperature of each pixel (from the thermal correction). + sensor_temp_c : 1D array + The temperature of the sensor for each line of the (for the C-channel). + saturation_c : 2D array + Information about the saturation of the C-channel. + saturation_vis : 2D array + Information about the saturation of the Vis-channel. + summation : int + The downtrack summing. + bits_per_data : int + The compression rate in bits per data. + data_quality : int + Information about the data quality, from 0 to 5 depending on missing lines and + compression errors. (See SOFT09_readme.txt for more details.) lrec : int The number of bytes in each physical record in the data product file. nrec : int @@ -111,6 +128,10 @@ class omegapy.omega_data.OMEGAdata(obs='', empty=False, data_path=_omega_bin_pat Number of parameters describing the geometry of the observation. point_mode : str The pointing mode of the instrument. + target : str + The name of the target of the observation ('MARS', 'PHOBOS' or 'DEIMOS') . + mode_channel : int + Information about the presence of each channel. orient : array The vector orientation of the spacecraft. subsol_lat : float @@ -491,6 +512,37 @@ omegapy.omega_data.get_omega_py_path(): The new path of the OMEGA python-made files. ~~~ +~~~python +omegapy.omega_data.get_names(omega_list): + Return the array of the observation ID of each OMEGA/MEx observation in omega_list. + + Parameters + ========== + omega_list : array of OMEGAdata + The input array of OMEGA observations. + + Returns + ======= + names : ndarray + The array of the omega_list observations ID. +~~~ + +~~~python +omegapy.omega_data.get_ls(omega_list): + """Return the array of the Solar longitude of each OMEGA/MEx observation in omega_list. + + Parameters + ========== + omega_list : array of OMEGAdata + The input array of OMEGA observations. + + Returns + ======= + ls : ndarray + The array of the omega_list Ls. +~~~ + + ### Update quality ~~python omegapy.omega_data.update_cube_quality(obs_name='ORB*.pkl', folder='auto', version=_Version, diff --git a/omegapy/omega_data.py b/omegapy/omega_data.py index 1a2e356..a4157d2 100644 --- a/omegapy/omega_data.py +++ b/omegapy/omega_data.py @@ -3,7 +3,7 @@ ## omega_data.py ## Created by Aurélien STCHERBININE -## Last modified by Aurélien STCHERBININE : 31/03/2020 +## Last modified by Aurélien STCHERBININE : 20/04/2020 ##---------------------------------------------------------------------------------------- """Importation of OMEGA observations in the OMEGAdata class. @@ -31,7 +31,7 @@ # Name of the current file _py_file = 'omega_data.py' -_Version = 1.3 +_Version = 1.4 # Path of the package files package_path = os.path.abspath(os.path.dirname(__file__)) @@ -100,6 +100,19 @@ class OMEGAdata: The longitude grid of the observation (from the edge of the pixels). surf_temp : 2D array The retrieved surface temperature of each pixel (from the thermal correction). + sensor_temp_c : 1D array + The temperature of the sensor for each line of the (for the C-channel). + saturation_c : 2D array + Information about the saturation of the C-channel. + saturation_vis : 2D array + Information about the saturation of the Vis-channel. + summation : int + The downtrack summing. + bits_per_data : int + The compression rate in bits per data. + data_quality : int + Information about the data quality, from 0 to 5 depending on missing lines and + compression errors. (See SOFT09_readme.txt for more details.) lrec : int The number of bytes in each physical record in the data product file. nrec : int @@ -114,6 +127,10 @@ class OMEGAdata: Number of parameters describing the geometry of the observation. point_mode : str The pointing mode of the instrument. + target : str + The name of the target of the observation ('MARS', 'PHOBOS' or 'DEIMOS') . + mode_channel : int + Information about the presence of each channel. orient : array The vector orientation of the spacecraft. subsol_lat : float @@ -182,7 +199,14 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): 'L' : np.arange(137, 256)} self.lon_grid = np.array([[]]) self.lat_grid = np.array([[]]) + self.sensor_temp_c = np.array([]) + self.saturation_c = np.array([[]]) + self.saturation_vis = np.array([[]]) self.surf_temp = np.array([[]]) + self.summation = None + self.bits_per_data = None + self.data_quality = None + self.mode_channel = None # Nav self.lrec = None self.nrec = None @@ -199,6 +223,7 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): self.min_lon = None self.max_lon = None self.slant = None + self.target = None else: idl = pidly.IDL() @@ -209,7 +234,8 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): return None nomfic0 = obs_name[obs_name.rfind('/')+1:-4] # Récupération nom + décodage UTF-8 idl("readomega_vpy, '{0}', ldat, jdat, wvl, ic, specmars, ".format(nomfic0) - + "latitude, longitude, emergence, incidence, altitude, solarlongi, ut_time, geocube") + + "latitude, longitude, emergence, incidence, altitude, solarlongi, ut_time, " + + "geocube, temperature, saturation_c, saturation_vis") print("\n\033[01;34mComputing data extraction and correction...\033[0m", end=' ') # Extract values from the idl session @@ -220,7 +246,8 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): ic = data_dict['ic'] specmars = data_dict['specmars'] infos_dict = idl.ev_list(['latitude', 'longitude', 'emergence', 'incidence', - 'altitude', 'solarlongi', 'ut_time', 'geocube'], use_cache=True) + 'altitude', 'solarlongi', 'ut_time', 'geocube', + 'temperature', 'saturation_c', 'saturation_vis'], use_cache=True) lat = infos_dict['latitude'] lon = infos_dict['longitude'] alt = infos_dict['altitude'] @@ -229,6 +256,9 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): ls = infos_dict['solarlongi'] utc = infos_dict['ut_time'] geocube = infos_dict['geocube'] + temperature = infos_dict['temperature'] + saturation_c = infos_dict['saturation_c'] + saturation_vis = infos_dict['saturation_vis'] # Close the idl session idl.close() # Correction of OMEGA data (same as clean_spec.pro) @@ -287,28 +317,48 @@ def __init__(self, obs='', empty=False, data_path=_omega_bin_path): self.lam_ma = lam_mask self.lat_grid = lat_grid self.lon_grid = lon_grid + self.sensor_temp_c = temperature.astype(np.float64) + self.saturation_c = saturation_c.astype(np.float64) + self.saturation_vis = saturation_vis.astype(np.float64) #-------------------------- - # Data from the .NAV file + # Data from the .QUB header #-------------------------- - nav = _read_header(obs_name[:-4] + '.NAV') - npixel, npara, nscan = np.array(nav['CORE_ITEMS'][1:-1].split(','), dtype=np.int64) - self.lrec = np.int64(nav['RECORD_BYTES']) - self.nrec = np.int64(nav['LABEL_RECORDS']) - self.sol_dist_au = np.float64(nav['SOLAR_DISTANCE']) / 14960e4 - npixel, npara, nscan = np.array(nav['CORE_ITEMS'][1:-1].split(','), dtype=np.int64) + hd_qub = _read_header(obs_name[:-4] + '.QUB') + self.summation = np.int64(hd_qub['DOWNTRACK_SUMMING']) + self.bits_per_data = np.float64(hd_qub['INST_CMPRS_RATE']) + self.data_quality = np.int64(hd_qub['DATA_QUALITY_ID']) + mode_channel_tmp = hd_qub['COMMAND_DESC'][34:36] + if mode_channel_tmp == 'EF': + self.mode_channel = 1 + elif mode_channel_tmp == '80': + self.mode_channel = 2 + elif mode_channel_tmp == 'C7': + self.mode_channel = 3 + else: + self.mode_channel = mode_channel_tmp + #-------------------------- + # Data from the .NAV header + #-------------------------- + hd_nav = _read_header(obs_name[:-4] + '.NAV') + npixel, npara, nscan = np.array(hd_nav['CORE_ITEMS'][1:-1].split(','), dtype=np.int64) + self.lrec = np.int64(hd_nav['RECORD_BYTES']) + self.nrec = np.int64(hd_nav['LABEL_RECORDS']) + self.sol_dist_au = np.float64(hd_nav['SOLAR_DISTANCE']) / 14960e4 + npixel, npara, nscan = np.array(hd_nav['CORE_ITEMS'][1:-1].split(','), dtype=np.int64) self.npixel = npixel self.npara = npara self.nscan = nscan - self.point_mode = nav['SPACECRAFT_POINTING_MODE'][1:-1] - self.orient = np.array(nav['SPACECRAFT_ORIENTATION'][1:-1].split(','), dtype=np.int64) - # self.ls = np.float64(nav['SOLAR_LONGITUDE']) - self.subsol_lon = np.float64(nav['SUB_SOLAR_LONGITUDE']) - self.subsol_lat = np.float64(nav['SUB_SOLAR_LATITUDE']) - self.min_lat = np.float64(nav['MINIMUM_LATITUDE']) - self.max_lat = np.float64(nav['MAXIMUM_LATITUDE']) - self.min_lon = np.float64(nav['WESTERNMOST_LONGITUDE']) - self.max_lon = np.float64(nav['EASTERNMOST_LONGITUDE']) - self.slant = np.float64(nav['SLANT_DISTANCE']) + self.point_mode = hd_nav['SPACECRAFT_POINTING_MODE'][1:-1] + self.orient = np.array(hd_nav['SPACECRAFT_ORIENTATION'][1:-1].split(','), dtype=np.int64) + # self.ls = np.float64(hd_nav['SOLAR_LONGITUDE']) + self.subsol_lon = np.float64(hd_nav['SUB_SOLAR_LONGITUDE']) + self.subsol_lat = np.float64(hd_nav['SUB_SOLAR_LATITUDE']) + self.min_lat = np.float64(hd_nav['MINIMUM_LATITUDE']) + self.max_lat = np.float64(hd_nav['MAXIMUM_LATITUDE']) + self.min_lon = np.float64(hd_nav['WESTERNMOST_LONGITUDE']) + self.max_lon = np.float64(hd_nav['EASTERNMOST_LONGITUDE']) + self.slant = np.float64(hd_nav['SLANT_DISTANCE']) + self.target = hd_nav['TARGET_NAME'] #-------------------------- temp_init = np.zeros(self.lat.shape) temp_init[:] = np.nan @@ -360,7 +410,14 @@ def __copy__(self): new_omega.lam_ma = self.lam_ma new_omega.lon_grid = self.lon_grid new_omega.lat_grid = self.lat_grid + new_omega.sensor_temp_c = self.sensor_temp_c + new_omega.saturation_c = self.saturation_c + new_omega.saturation_vis = self.saturation_vis new_omega.surf_temp = self.surf_temp + new_omega.summation = self.summation + new_omega.bits_per_data = self.bits_per_data + new_omega.data_quality = self.data_quality + new_omega.mode_channel = self.mode_channel # Nav new_omega.lrec = self.lrec new_omega.nrec = self.nrec @@ -377,6 +434,7 @@ def __copy__(self): new_omega.min_lon = self.min_lon new_omega.max_lon = self.max_lon new_omega.slant = self.slant + new_omega.target = self.target # Infos new_omega.quality = self.quality new_omega.therm_corr = self.therm_corr @@ -409,7 +467,14 @@ def __deepcopy__(self, memo): new_omega.lam_ma = deepcopy(self.lam_ma, memo) new_omega.lon_grid = deepcopy(self.lon_grid, memo) new_omega.lat_grid = deepcopy(self.lat_grid, memo) + new_omega.sensor_temp_c = deepcopy(self.sensor_temp_c, memo) + new_omega.saturation_c = deepcopy(self.saturation_c, memo) + new_omega.saturation_vis = deepcopy(self.saturation_vis, memo) new_omega.surf_temp = deepcopy(self.surf_temp, memo) + new_omega.summation = deepcopy(self.summation, memo) + new_omega.bits_per_data = deepcopy(self.bits_per_data, memo) + new_omega.data_quality = deepcopy(self.data_quality, memo) + new_omega.mode_channel = deepcopy(self.mode_channel, memo) # Nav new_omega.lrec = deepcopy(self.lrec, memo) new_omega.nrec = deepcopy(self.nrec, memo) @@ -426,6 +491,7 @@ def __deepcopy__(self, memo): new_omega.min_lon = deepcopy(self.min_lon, memo) new_omega.max_lon = deepcopy(self.max_lon, memo) new_omega.slant = deepcopy(self.slant, memo) + new_omega.target = deepcopy(self.target, memo) # Infos new_omega.quality = deepcopy(self.quality, memo) new_omega.therm_corr = deepcopy(self.therm_corr, memo) @@ -507,6 +573,8 @@ def _read_header(filename): elif 'SPACECRACRAFT_POINTING_MODE' in keys: header_dict['SPACECRAFT_POINTING_MODE'] = deepcopy(header_dict['SPACECRACRAFT_POINTING_MODE']) del header_dict['SPACECRACRAFT_POINTING_MODE'] + else: + header_dict['SPACECRAFT_POINTING_MODE'] = '"N/A"' if header_dict['SPACECRAFT_POINTING_MODE'] == '"UNK"': header_dict['SPACECRAFT_POINTING_MODE'] = '"UNKNOWN"' # Sortie @@ -679,7 +747,7 @@ def autosave_omega(omega, folder='auto', base_folder=_omega_py_path, security=Tr folder : str, optional (default 'auto') The subfolder to save the data. | If 'auto' -> folder = 'vX.X', where X.X is the Version of the current code. - base_folder : str, optional (defaul _omega_py_path) + base_folder : str, optional (default _omega_py_path) The base folder path. security : bool, optional (default True) Enable / disable checking before overwriting a file. @@ -1401,6 +1469,42 @@ def get_omega_py_path(): """ return deepcopy(_omega_py_path) +def get_names(omega_list): + """Return the array of the observation ID of each OMEGA/MEx observation in omega_list. + + Parameters + ========== + omega_list : array of OMEGAdata + The input array of OMEGA observations. + + Returns + ======= + names : ndarray + The array of the omega_list observations ID. + """ + names = [] + for omega in omega_list: + names.append(omega.name) + return names + +def get_ls(omega_list): + """Return the array of the Solar longitude of each OMEGA/MEx observation in omega_list. + + Parameters + ========== + omega_list : array of OMEGAdata + The input array of OMEGA observations. + + Returns + ======= + ls : ndarray + The array of the omega_list Ls. + """ + ls = [] + for omega in omega_list: + ls.append(omega.ls) + return ls + ##---------------------------------------------------------------------------------------- ## Update cube quality def update_cube_quality(obs_name='ORB*.pkl', folder='auto', version=_Version, diff --git a/omegapy/omega_routines/readomega_vpy.pro b/omegapy/omega_routines/readomega_vpy.pro index 448d979..451a8a2 100644 --- a/omegapy/omega_routines/readomega_vpy.pro +++ b/omegapy/omega_routines/readomega_vpy.pro @@ -1,6 +1,6 @@ ;SOFT09 ;+ calculs fin + solarlongi -pro readomega_vpy, nomfic0, ldat, jdat, wvl, ic, specmars, latitude, longitude, emergence, incidence, altitude, solarlongi, ut_time, geocube +pro readomega_vpy, nomfic0, ldat, jdat, wvl, ic, specmars, latitude, longitude, emergence, incidence, altitude, solarlongi, ut_time, geocube, temperature, saturation_c, saturation_vis dirsoft = '' @@ -402,6 +402,18 @@ readf,2,atmorap close,2 +;saturation +summation=info(3) +;voie C : +;saturation_c=reform(idat(*,39,*))/summation +saturation_c=reform(idat(*,39,*)) & saturation_c(*,*)=0. +for i=0,(size(saturation_c))(1)-1 do saturation_c(i,*)=(reform(sdat0(39,*))-reform(idat(i,39,*)))/summation ;42? +;voie visible : +saturation_vis=reform(idat(*,299,*))/summation +;temperature voie C +temperature=reform(sdat1(0,2,*))*0.001 + + fin: close,/all end diff --git a/setup.py b/setup.py index 26bd080..ba0265a 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setuptools.setup( name='omegapy', - version='1.3.1', + version='1.4', author='Aurélien Stcherbinine', author_email='aurelien.stcherbinine@ias.u-psud.fr', description='Python tools for OMEGA/MEx observations analysis',