def __init__(self, in_north, in_south, in_east, in_west, in_near_range, in_swath_width): """ Init orbit caracteristics :param in_south: Southern latitude of the studied area :type in_south: float :param in_north: Northern latitude of the studied area :type in_north: float :param in_west: Western latitude of the studied area :type in_west: float :param in_east: Eastern longitude of the studied area :type in_east: float :param in_swath_width: Swath width :type in_swath_width: float :param in_near_range: NR cross track :type in_near_range: float """ my_api.printInfo("[findOrbit] == INIT ==") # Studied area self.north_lat = in_north self.south_lat = in_south self.east_lon = in_east self.west_lon = in_west # Simulation caracteristics self.near_range = in_near_range self.swath_width = in_swath_width
def __init__(self, IN_orbit_directory, IN_mission_start_time, IN_cycle_duration, IN_simulation_start_time, IN_simulation_stop_time): """ Constructor, initializes the class :param IN_orbit_directory: full path of directory containing orbit files :type IN_orbit_directory: string :param IN_mission_start_time: mission start time :type IN_mission_start_time: string :param IN_cycle_duration: cycle duration (in seconds) :type IN_cycle_duration: float :param IN_simulation_start_time: simulation start time :type IN_simulation_start_time: string :param IN_simulation_stop_time: simulation stop time :type IN_simulation_stop_time: string """ my_api.printInfo("[Passplan] == INIT ==") # Init self attributes from input parameters self.orbit_directory = IN_orbit_directory self.mission_start_time = IN_mission_start_time self.cycle_duration = IN_cycle_duration / 86400.0 # In days self.simulation_start_time = IN_simulation_start_time self.simulation_stop_time = IN_simulation_stop_time # Init processing attributes self.cycle_start = None self.cycle_stop = None self.cycles = None
def run_processing(self): """ Main process, computations are done here Returns: int. return code """ my_api.printInfo("[select_orbit_cnes] == PROCESSING... ==") # 1 - Modify coordinates if not coherent between each others if self.north < self.south: self.north, self.south = self.south, self.north if self.west < self.east: self.west, self.east = self.east, self.west # 2 - Init orbit class gdem_orbit = findOrbit(self.south, self.north, self.west, self.east, self.swath_width, self.near_range) # 3 - Compute orbit files specific to studied area prefix = os.path.join(self.output_directory, self.gdem_prefix) cycle_duration = gdem_orbit.orbit_over_dem(self.orbit_directory, prefix, self.azimuth_spacing, self.swath_width, in_mission_start_time=self.mission_start_time) # Compute pass plan if asked if self.makePassPlan == "yes": passplan = lib_passplan.Passplan(self.output_directory, self.mission_start_time, cycle_duration, self.simulation_start_time, self.simulation_stop_time) passplan.run_preprocessing() passplan.run_processing() my_api.printInfo("") return 0
def __init__(self, in_parameter_file, in_output_directory): """ Constructor: initializes the self attributes :param in_parameter_file: parameter file full path :type in_parameter_file: str :param in_output_directory: output directory full path :type in_output_directory: str """ my_api.printInfo("[select_orbit_cnes] == INIT ==") my_api.printInfo("[select_orbit_cnes] Parameter file = %s" % in_parameter_file) my_api.printInfo("[select_orbit_cnes] Output directory = %s" % in_output_directory) my_api.printInfo("") self.parameter_file = in_parameter_file self.output_directory = in_output_directory self.mission_name = None self.mission_start_time = None self.orbit_directory = None self.south = None self.north = None self.west = None self.east = None self.azimuth_spacing = None self.swath_width = None self.near_range = None self.makePassPlan = None self.simulation_start = None self.simulation_stop = None
def run_preprocessing(self): """ Preprocessing: read the parameter file and initialize variables :return: return code (0=OK - 101=error) :rtype: int """ my_api.printInfo("[select_orbit_cnes] == PRE-PROCESSING... ==") return_code = 0 # 1 - Read the RDF parameter file param_reader = Input_Reader(self.parameter_file) # Init reader param_reader.read_param_file() # Read the file # 2 - Find orbit directory path try: self.orbit_directory = param_reader.get_orbit_repository() if not os.path.exists(self.orbit_directory): raise FileNotFoundError("Orbit repository doesn't exist: %s" % self.orbit_directory) except: raise FileNotFoundError("Orbit repository not populated in the configuration file") return_code = 101 # 3 - Set class attributes values self.mission_name = param_reader.get_mission_name() self.mission_start_time = param_reader.get_mission_start_time() self.north = float(param_reader.get_north_latitude()) self.south = float(param_reader.get_south_latitude()) self.east = float(param_reader.get_east_longitude()) self.west = float(param_reader.get_west_longitude()) self.azimuth_spacing = float(param_reader.get_azimuth_spacing()) self.near_range = float(param_reader.get_near_range()) self.swath_width = float(param_reader.get_swath()) self.gdem_prefix = param_reader.get_gdem_prefix() self.makePassPlan = param_reader.get_make_pass_plan() self.simulation_start_time = param_reader.get_simulation_start() self.simulation_stop_time = param_reader.get_simulation_stop() my_api.printInfo("") return return_code
def run_postprocessing(self): """ Postprocessing, at this point, the output product is written, and memory structures are freed, file are closed. Returns: int. return code """ my_api.printInfo("[select_orbit_cnes] == POST-PROCESSING... ==") # If an output file has to be written, use the API function to know # where you can write it: # output_location = self.api.get_output_folder() # Keep this as the last line of this function #self.api.end_module(True) my_api.printInfo("") return 0
from ressources.utils import my_timer, my_api if __name__ == '__main__': # 0 - Parse inline parameters parser = argparse.ArgumentParser(description="Compute orbit files specific to the studied area") parser.add_argument("param_file", help="full path to the parameter file (*.rdf)") parser.add_argument("-v", "--verbose", help="Verbose level (DEBUG or INFO=default)", nargs="?", type=str, default="INFO") parser.add_argument("-l", "--logfile", help="Write prints to a logfile in addition to the console", nargs='?', type=bool, default=True, const=True) parser.add_argument("output_dir", help="full path to the output directory") args = parser.parse_args() # Verbose level verbose_level = my_api.setVerbose(args.verbose) my_api.printInfo("Verbose level = {}".format(verbose_level)) if args.logfile: logFile = os.path.join(os.path.dirname(args.param_file), "select_orbit_" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + ".log") my_api.initLogger(logFile, verbose_level) my_api.printInfo("Log file = {}".format(logFile)) else: my_api.printInfo("No log file ; print info on screen") my_api.printInfo("") my_api.printInfo("===== select_orbit_cnes = BEGIN =====") my_api.printInfo("") timer = my_timer.Timer() timer.start() try:
def orbit_over_dem(self, in_orbit_directory, in_file_prefix, in_azimuth_spacing, in_swath_width, in_mission_name="SWOT", in_mission_start_time="0000_00_00"): """ Extract parts of orbit from input files, that cover the studied area. Output these parts with the sampling specified in configuration file. :param in_orbit_directory: directory of input orbit files :type in_orbit_directory: str :param in_file_prefix: prefix for output files (include full path) :type in_file_prefix: str :param in_azimuth_spacing: azimuth spacing for output file, used to interpolate input orbit files :type in_azimuth_spacing: float :param in_swath_width: swath width :type in_swath_width: float :param in_mission_name: mission name (default=SWOT), used in case of specific processing :type in_mission_name: str :param in_mission_start_time: mission start time :type in_mission_start_time: str :return: out_cycle_duration = cycle duration, read from input orbit files :rtype: float """ my_api.printInfo("[findOrbit] == orbit_over_dem ==") # DEM reference polygon as a shapely.geometry.box polygon_ref = box(self.south_lat, self.west_lon, self.north_lat, self.east_lon) cpt = 0 # Find all orbit files in the input directory orbit_file_list = os.listdir(os.path.expandvars(in_orbit_directory)) orbit_file_list.sort() for orbit_file in orbit_file_list: if ~os.path.isdir(orbit_file): # Don't go down the file tree index_over_dem = [ ] # Init list of indices of nadir points corresponding to part of orbit overfliying the studied area # Open orbit file and get some variables data_orbit = Dataset( os.path.join(os.path.expandvars(in_orbit_directory), orbit_file)) lat = data_orbit.variables['latitude'][:] lon = data_orbit.variables['longitude'][:] out_cycle_duration = data_orbit.getncattr( 'repeat_cycle_period') if not self.is_ref_poly_in_orbit(polygon_ref, lon, lat): my_api.printInfo("> SKIP : orbit file = %s" % orbit_file) cpt += 1 continue for ind_pt in range(lat[:].size - RECORD_MARGIN): polygon_data_right, polygon_data_left = self.get_polygon_right_left_swath( lon[ind_pt], lat[ind_pt], lon[ind_pt + RECORD_MARGIN], lat[ind_pt + RECORD_MARGIN]) # Save file if intersection with DEM > 0 #~ if ((polygon_data_left.intersection(polygon_ref).area > 0 or polygon_data_right.intersection( #~ polygon_ref).area > 0) and (-10 < (lat[ind_pt] - self.south_lat) < 10 and -10 < ( #~ lon[ind_pt] - self.east_lon) < 10)): if polygon_data_left.intersection( polygon_ref ).area > 0 or polygon_data_right.intersection( polygon_ref).area > 0: if ind_pt not in index_over_dem: index_over_dem.append(ind_pt) if ind_pt + RECORD_MARGIN < lat[:].size: index_over_dem.append(ind_pt + RECORD_MARGIN) if len(index_over_dem) > 1: my_api.printInfo("> Orbit file = %s" % orbit_file) # Data sampling nb_sampling_points = int( vincenty.dist_vincenty( lat[index_over_dem[0]], lon[index_over_dem[0]], lat[index_over_dem[-1]], lon[index_over_dem[-1]]) / in_azimuth_spacing) my_api.printInfo(" Number of sampling points = %d" % nb_sampling_points) # Cut valid files and save in new files if in_mission_name == "SWOT": pass_num = int( orbit_file.split('.')[0].split("_")[-1] ) + 332 # Compute pass number wrt SWOT KMLs available on AVISO+ (sept2015-v2) if pass_num > 584: pass_num -= 584 else: pass_num = int(orbit_file.split('.')[0].split("_")[-1]) out_filename = in_file_prefix + "_cycle_0001_pass_%04d.nc" % pass_num my_api.printInfo(" Save as %s" % out_filename) output_orbit_file = Dataset(out_filename, "w", format="NETCDF4") # SWOT only: update time vector to be coherent with new pass number tmp_time = data_orbit.variables['time'][:] if in_mission_name == "SWOT": tmp_time += 1024820.9861689 # = 332/2 (orbit number) * 6173.620398608 (nodal period) tmp_ind = np.where(tmp_time > out_cycle_duration)[0] if len(tmp_ind) > 0: tmp_time[tmp_ind] -= out_cycle_duration # Dimensions output_orbit_file.createDimension('record', nb_sampling_points) # Variables for v_name, varin in iter(data_orbit.variables.items()): outVar = output_orbit_file.createVariable( v_name, varin.datatype, 'record') outVar.setncatts( {k: varin.getncattr(k) for k in varin.ncattrs()}) # Linear regression of variable if v_name == "time": # Specific consideration of time variable lin_reg = np.polyfit(index_over_dem[:], tmp_time[index_over_dem], 1) else: lin_reg = np.polyfit(index_over_dem[:], varin[index_over_dem], 1) give_output = np.poly1d(lin_reg) output_scale = np.linspace(index_over_dem[0], index_over_dem[-1], nb_sampling_points) outVar[:] = give_output(output_scale) # Creating x, y and z variables x, y, z = inversionCore.convert_llh2ecef( output_orbit_file.variables['latitude'][:], output_orbit_file.variables['longitude'][:], output_orbit_file.variables['altitude'][:], GEN_RAD_EARTH, GEN_RAD_EARTH_POLE) outVar = output_orbit_file.createVariable( 'x', np.float64, 'record') outVar[:] = x[:] outVar = output_orbit_file.createVariable( 'y', np.float64, 'record') outVar[:] = y[:] outVar = output_orbit_file.createVariable( 'z', np.float64, 'record') outVar[:] = z[:] # Global attributes output_orbit_file.setncattr('repeat_cycle_period', out_cycle_duration) output_orbit_file.setncattr('pass_number', pass_num) output_orbit_file.setncattr('cycle_number', 1) output_orbit_file.setncattr('beginning_of_mission_time', 0.) output_orbit_file.setncattr('azimuth_spacing', in_azimuth_spacing) output_orbit_file.setncattr('swath_width', in_swath_width) output_orbit_file.setncattr('release', "select_orbit_cnes") output_orbit_file.setncattr('mission start time', in_mission_start_time) output_orbit_file.setncattr('cycle_duration', out_cycle_duration) output_orbit_file.setncattr('dem south latitude', self.south_lat) output_orbit_file.setncattr('dem north latitude', self.north_lat) output_orbit_file.setncattr('dem west longitude', self.west_lon) output_orbit_file.setncattr('dem east longitude', self.east_lon) # Close output orbit file output_orbit_file.close() else: my_api.printInfo("> NOT KEPT: orbit file = %s" % orbit_file) # Close input orbit file data_orbit.close() # Return cycle duration return out_cycle_duration