def orbit2swath(modelbox, p, orb, die_on_error): '''Computes the swath of SWOT satellites on a subdomain from an orbit. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Swath parameters (half gap distance p.halfgap, half swath distance p.halfswath, along track resolution p.delta_al, across track resolution p.delta_ac). \n Outputs are netcdf files containing SWOT grid (along track distance x_al, across track distance from nadir x_ac, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' ''' Compute orbit from Swath ''' # - Load altimeter orbit x_al = orb.x_al stime = orb.time lon = orb.lon lat = orb.lat tcycle = orb.cycle al_cycle = orb.al_cycle passtime = orb.passtime # - Compute accross track distances from nadir # Number of points in half of the swath nhalfswath = int((p.halfswath - p.halfgap) / p.delta_ac) + 1 # Across track distance from nadir x_ac = numpy.zeros((2 * nhalfswath)) for i in range(0, int(nhalfswath)): x_ac[i] = -(nhalfswath - i) * p.delta_ac - p.halfgap + p.delta_ac x_ac[i + nhalfswath] = i * p.delta_ac + p.halfgap # - Computation of SWOT grid and storage by passes logger.info('\n Compute SWOT grid') # Detect first pass that is in the subdomain ipass0 = 0 # strpass = [] # Loop on all passes after the first pass detected jobs = [] p2 = mod_tools.todict(p) for ipass in range(ipass0, numpy.shape(passtime)[0]): jobs.append([ ipass, p2, passtime, stime, x_al, x_ac, tcycle, al_cycle, nhalfswath, lon, lat, orb.timeshift ]) try: ok = make_swot_grid(p.proc_count, jobs, die_on_error, p.progress_bar) except run_simulator.DyingOnError: logger.error('An error occurred and all errors are fatal') sys.exit(1) if p.progress_bar is True: mod_tools.update_progress(1, 'All swaths have been processed', ' ') else: logger.info('All swaths have been processed') return None
def orbit2swath(modelbox, p, orb, die_on_error): '''Computes the swath of SWOT satellites on a subdomain from an orbit. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Swath parameters (half gap distance p.halfgap, half swath distance p.halfswath, along track resolution p.delta_al, across track resolution p.delta_ac). \n Outputs are netcdf files containing SWOT grid (along track distance x_al, across track distance from nadir x_ac, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' ''' Compute orbit from Swath ''' # - Load altimeter orbit x_al = orb.x_al stime = orb.time lon = orb.lon lat = orb.lat tcycle = orb.cycle al_cycle = orb.al_cycle passtime = orb.passtime # - Compute accross track distances from nadir # Number of points in half of the swath nhalfswath = int((p.halfswath-p.halfgap)/p.delta_ac) + 1 # Across track distance from nadir x_ac = numpy.zeros((2*nhalfswath)) for i in range(0, int(nhalfswath)): x_ac[i] = -(nhalfswath - i)*p.delta_ac - p.halfgap + p.delta_ac x_ac[i + nhalfswath] = i * p.delta_ac + p.halfgap # - Computation of SWOT grid and storage by passes logger.info('\n Compute SWOT grid') # Detect first pass that is in the subdomain ipass0 = 0 # strpass = [] # Loop on all passes after the first pass detected jobs = [] p2 = mod_tools.todict(p) for ipass in range(ipass0, numpy.shape(passtime)[0]): jobs.append([ipass, p2, passtime, stime, x_al, x_ac, tcycle, al_cycle, nhalfswath, lon, lat, orb.timeshift]) try: ok = make_swot_grid(p.proc_count, jobs, die_on_error, p.progress_bar) except run_simulator.DyingOnError: logger.error('An error occurred and all errors are fatal') sys.exit(1) if p.progress_bar is True: mod_tools.update_progress(1, 'All swaths have been processed', ' ') else: logger.info('All swaths have been processed') return None
def orbit2nadir(modelbox, p, orb, die_on_error): '''Computes the nadir satellites on a subdomain from an orbit. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Nadir parameters (along track resolution p.delta_al). \n Outputs are netcdf files containing SWOT tracks (along track distance x_al, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' ''' Compute orbit from Swath ''' # - Load altimeter orbit x_al = orb.x_al stime = orb.time lon = orb.lon lat = orb.lat tcycle = orb.cycle al_cycle = orb.al_cycle passtime = orb.passtime # - Computation of Nadir track and storage by passes logger.info('\n Compute Nadir track') # Detect first pass that is in the subdomain ipass0 = 0 # strpass = [] # Loop on all passes after the first pass detected jobs = [] p2 = mod_tools.todict(p) for ipass in range(ipass0, numpy.shape(passtime)[0]): jobs.append([ ipass, p2, passtime, stime, x_al, tcycle, al_cycle, lon, lat, orb.timeshift ]) try: ok = make_nadir_grid(p.proc_count, jobs, die_on_error, p.progress_bar) except run_simulator.DyingOnError: logger.error('An error occurred and all errors are fatal') sys.exit(1) if p.progress_bar is True: mod_tools.update_progress(1, 'All swaths have been processed', ' ') else: logger.info('All swaths have been processed') return None
def orbit2nadir(modelbox, p, orb, die_on_error): '''Computes the nadir satellites on a subdomain from an orbit. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Nadir parameters (along track resolution p.delta_al). \n Outputs are netcdf files containing SWOT tracks (along track distance x_al, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' ''' Compute orbit from Swath ''' # - Load altimeter orbit x_al = orb.x_al stime = orb.time lon = orb.lon lat = orb.lat tcycle = orb.cycle al_cycle = orb.al_cycle passtime = orb.passtime # - Computation of Nadir track and storage by passes logger.info('\n Compute Nadir track') # Detect first pass that is in the subdomain ipass0 = 0 # strpass = [] # Loop on all passes after the first pass detected jobs = [] p2 = mod_tools.todict(p) for ipass in range(ipass0, numpy.shape(passtime)[0]): jobs.append([ipass, p2, passtime, stime, x_al, tcycle, al_cycle, lon, lat, orb.timeshift]) try: ok = make_nadir_grid(p.proc_count, jobs, die_on_error, p.progress_bar) except run_simulator.DyingOnError: logger.error('An error occurred and all errors are fatal') sys.exit(1) if p.progress_bar is True: mod_tools.update_progress(1, 'All swaths have been processed', ' ') else: logger.info('All swaths have been processed') return None
def run_nadir(p, die_on_error=False): # - Initialize some parameters values timestart = datetime.datetime.now() mod_tools.initialize_parameters(p) p.nadir = True p.karin = False p.phase = False p.roll = False p.baseline_dilation = False p.timing = False p.halfswath = 60. # - Progress bar variables are global global ntot # Build model time steps from parameter file modeltime = numpy.arange(0, p.nstep * p.timestep, p.timestep) # - Read list of user model files """ if p.file_input is not None: list_file = [line.strip() for line in open(p.file_input)] if len(modeltime) > len(list_file): logger.error('There is not enough model files in the list of ' 'files') sys.exit(1) else: list_file = None # ############################################ # Select the spatial and temporal domains # ############################################ # - Read model input coordinates ''' model_data, list_file = mod.load_coordinate_model(p) # if no modelbox is specified (modelbox=None), the domain of the input data # is taken as a modelbox # coordinates from the region defined by modelbox are selected logger.debug('Read input') if p.modelbox is not None: modelbox = numpy.array(p.modelbox, dtype='float') # Use convert to 360 data modelbox[0] = (modelbox[0] + 360) % 360 if modelbox[1] != 360: modelbox[1] = (modelbox[1] + 360) % 360 else: if p.file_input is not None: modelbox = model_data.calc_box() else: logger.error('modelbox should be provided if no model file is ' 'provided') sys.exit() p.modelbox_calc = modelbox logger.debug(p.file_input) if p.file_input is not None: model_data.read_coordinates() # Select model data in the region modelbox model_data.len_coord = len(numpy.shape(model_data.vlon)) if p.grid == 'regular' or model_data.len_coord == 1: if modelbox[0] < modelbox[1]: _i_lon = numpy.where(((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)))[0] else: _i_lon = numpy.where(((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)))[0] model_data.model_index_lon = _i_lon _i_lat = numpy.where(((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1)))[0] model_data.model_index_lat = _i_lat model_data.vlon = model_data.vlon[model_data.model_index_lon] model_data.vlat = model_data.vlat[model_data.model_index_lat] else: if modelbox[0] < modelbox[1]: _i_box = numpy.where(((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) else: _i_box = numpy.where(((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) model_data.model_index = _i_box model_data.vlon = model_data.vlon[model_data.model_index] model_data.vlat = model_data.vlat[model_data.model_index] model_data.model = p.model model_data.vloncirc = numpy.rad2deg(numpy.unwrap(model_data.vlon)) # Ugly trick when model box is [0 360] to avoid box being empty (360=0%360) if modelbox[1] == 0: modelbox[1] = 359.99 # - Initialize random coefficients that are used to compute # random errors following the specified spectrum err, errnad = mod.load_error(p, nadir_alone=nadir_alone) # - Compute interpolated SSH and errors for each pass, at each # cycle logger.info('Compute interpolated SSH and errors:') # Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) if len(modeltime) > len(list_file): logger.error('There is not enough model files in the list of' ' files') sys.exit(1) # Initialize progress bar variables ntot = 1 # Initialize list of satellites if not isinstance(p.filesat, list): p.filesat = [p.filesat] for filesat in p.filesat: # Select satellite # ntmp, nfilesat = os.path.split(filesat[istring:-4]) nfilesat = os.path.basename(os.path.splitext(filesat)[0]) # Make satellite orbit grid if p.makesgrid is True: logger.warning('\n Force creation of satellite grid') ngrid = build_swath.makeorbit(modelbox, p, orbitfile=filesat) ngrid.file = '{}{}_grid.nc'.format((p.filesgrid).strip(), nfilesat.strip()) ngrid.write_orb() ngrid.ipass = nfilesat ngrid.gridfile = '{}{}_grid.nc'.format((p.filesgrid).strip(), nfilesat.strip()) else: # To be replaced by load_ngrid gridfile = '{}{}_grid.nc'.format((p.filesgrid).strip(), nfilesat.strip()) ngrid = rw_data.Sat_nadir(nfile=gridfile) ngrid.file = gridfile ngrid.ipass = nfilesat cycle = 0 x_al = [] al_cycle = 0 timeshift = 0 ngrid.load_orb(cycle=cycle, x_al=x_al, al_cycle=al_cycle, timeshift=timeshift) ngrid.loncirc = numpy.rad2deg(numpy.unwrap(ngrid.lon)) # ngrid=load_ngrid(sgridfile, p) # Select model data around the swath to reduce interpolation # cost in griddata # if p.file_input is not None: # _ind = numpy.where((numpy.min(ngrid.lon) <= model_data.vlon) # & (model_data.vlon <= numpy.max(ngrid.lon)) # & (numpy.min(ngrid.lat) <= model_data.vlat) # & (model_data.vlat <= numpy.max(ngrid.lat))) # model_index = _ind # - Generate and nadir-like data: # Compute number of cycles needed to cover all nstep model timesteps rcycle = (p.timestep * p.nstep) / float(ngrid.cycle) ncycle = int(rcycle) # Loop on all cycles for cycle in range(0, ncycle + 1): ### TODO move this line somwhere where we have ifile information #if ifile > (p.nstep/p.timestep + 1): # break # Create SWOT-like and Nadir-like data if p.file_input is None: model_data = [] logger.debug('compute SSH nadir') nfile = numpy.shape(p.filesat)[0] * rcycle create = mod.create_Nadirlikedata(cycle, nfile, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=True) SSH_true_nadir, vindice, time, progress = create # SSH_true_nadir, vindice_nadir=create_Nadirlikedata(cycle, sgrid, # ngrid, model_data, modeltime, err, errnad, p) # Save outputs in a netcdf file ngrid.gridfile = filesat if (~numpy.isnan(vindice)).any() or p.file_input is None: err = errnad err.wtnadir = numpy.zeros((1)) err.wet_tropo2nadir = numpy.zeros((1)) logger.debug('write file') mod.save_Nadir(cycle, ngrid, errnad, err, p, time=time, vindice_nadir=vindice, SSH_true_nadir=SSH_true_nadir) del time # if p.file_input: del index ngrid.lon = (ngrid.lon + 360) % 360 if p.file_input: model_data.vlon = (model_data.vlon + 360) % 360 modelbox[0] = (modelbox[0] + 360) % 360 modelbox[1] = (modelbox[1] + 360) % 360 del ngrid if progress != 1: str1 = 'All passes have been processed' progress = mod_tools.update_progress(1, str1, '') # - Write Selected parameters in a txt file timestop = datetime.datetime.now() timestop = timestop.strftime('%Y%m%dT%H%M%SZ') timestart = timestart.strftime('%Y%m%dT%H%M%SZ') op_file = 'nadir_simulator_{}_{}.output'.format(timestart, timestop) op_file = os.path.join(p.outdatadir, op_file) rw_data.write_params(p, op_file) logger.info("\nSimulated orbit files have been written in {}".format( p.outdatadir)) logger.info("----------------------------------------------------------")
def create_Nadirlikedata(cycle, ntotfile, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=False): # - Progress bar variables are global global istep global ntot global ifile errnad.wet_tropo1nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.wt = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice = numpy.zeros(numpy.shape(ngrid.lon))*numpy.nan # Definition of the time in the model date1 = cycle * ngrid.cycle time = ngrid.time + date1 # Look for satellite data that are beween step-p.timesetp/2 and # setp+p.timestep/2 if p.file_input is not None: time_shift_end = time[-1] - ngrid.timeshift time_shift_start = time[0] - ngrid.timeshift model_tmin = modeltime - p.timestep/2. model_tmax = modeltime + p.timestep/2. index_filemodel = numpy.where((time_shift_end >= model_tmin) & (time_shift_start < model_tmax)) # [0] # At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: if progress_bar: pstep = float(istep) / float(ntot) str1 = 'orbit: {}'.format(ngrid.ipass) str2 = 'model file: {}, cycle: {}'.format(list_file[ifile], cycle + 1) progress = mod_tools.update_progress(pstep, str1, str2) else: progress = None # If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1] > 0: ntot = ntot + numpy.shape(index_filemodel)[1] - 1 time_shift = (time - ngrid.timeshift) model_min = modeltime[ifile] - p.timestep/2. model_max = modeltime[ifile] + p.timestep/2. ind_nadir_time = numpy.where((time_shift >= model_min) & (time_shift < model_max)) if len(ind_nadir_time[0]) < 3: continue model_step_ctor = getattr(rw_data, model_data.model) nfile = os.path.join(p.indatadir, list_file[ifile]) model_step = model_step_ctor(p, nfile=nfile, var=p.var) if p.grid == 'regular' or model_data.len_coord == 1: model_step.read_var() SSH_model = model_step.vvar[model_data.model_index_lat, :] SSH_model = SSH_model[:, model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model = model_step.vvar # - Interpolate Model data along the nadir # track # Handle Greenwich line lon_model = + model_data.vlon lon_ngrid = + ngrid.lon if numpy.max(lon_grid) > 359: lon_ngrid = numpy.mod(lon_ngrid + 180., 360.) - 180. lon_model = numpy.mod(lon_model + 180., 360.) - 180. # if grid is regular, use interpolate.RectBivariateSpline to # interpolate if p.grid == 'regular' or model_data.len_coord == 1: # ########################TODO # To be moved to routine rw_data indsorted = numpy.argsort(model_data.vlon) model_data.vlon = model_data.vlon[indsorted] SSH_model = SSH_model[:, indsorted] interp = interpolate_regular_1D _ssh, Teval = interp(p, model_data.vlon, model_data.vlat, SSH_model, ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel(), Teval=None) SSH_true_nadir[ind_nadir_time[0]] = _ssh else: # Grid is irregular, interpolation can be done using pyresample # module if it is installed or griddata function from scipy. # Note that griddata is slower than pyresample functions. try: import pyresample as pr ngrid.lon = pr.utils.wrap_longitudes(ngrid.lon) model_data.vlon = pr.utils.wrap_longitudes(model_data.vlon) geomdef = pr.geometry.SwathDefinition ngrid_def = geomdef(lons=ngrid.lon[ind_nadir_time[0]], lats=ngrid.lat[ind_nadir_time[0]]) swath_def = geomdef(lons=model_data.vlon, lats=model_data.vlat) interp = interpolate_irregular_pyresample _ssh = interp(swath_def, SSH_model, ngrid_def, p.delta_al, interp_type=p.interpolation) SSH_true_nadir[ind_nadir_time[0]] = _ssh except ImportError: interp = interpolate.griddata _ssh = interp((model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) SSH_true_nadir[ind_nadir_time[0]] = _ssh if p.interpolation == 'nearest': if modelbox[0] > modelbox[1]: ind = numpy.where(((ngrid.lon < modelbox[0]) & (ngrid.lon > modelbox[1])) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3])) else: ind = numpy.where((ngrid.lon < modelbox[0]) | (ngrid.lon > modelbox[1]) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3])) SSH_true_nadir[ind] = numpy.nan vindice[ind_nadir_time[0]] = ifile istep += 1 else: if progress_bar: pstep = float(istep) / float(ntotfile * ntot) str1 = 'orbit: {}'.format(ngrid.ipass) cy1 = cycle + 1 str2 = 'model file: {}, cycle: {}'.format(list_file[ifile], cy1) progress = mod_tools.update_progress(pstep, str1, str2) else: progress = None istep += 1 errnad.make_error(ngrid, cycle, SSH_true_nadir, p) # , ind[0]) errnad.SSH = SSH_true_nadir + errnad.nadir + errnad.wet_tropo1nadir # del SSH_model, model_step, ind_nadir_time return SSH_true_nadir, vindice, time, progress
def run_simulator(p): # - Initialize some parameters values timestart = datetime.datetime.now() mod_tools.initialize_parameters(p) mod_tools.check_path(p) # - Progress bar variables are global global istep global ntot # - Read list of user model files """ if p.file_input is not None: list_file = [line.strip() for line in open(p.file_input)] else: list_file = None # - Read model input coordinates ''' # if no modelbox is specified (modelbox=None), the domain of the input # data is taken as a modelbox # coordinates from the region defined by modelbox are selected if p.file_input is not None: model_data_ctor = getattr(rw_data, p.model) nfile = os.path.join(p.indatadir, list_file[0]) model_data = model_data_ctor(p, nfile=nfile) if p.modelbox is not None: modelbox = numpy.array(p.modelbox, dtype='float') # Use convert to 360 data modelbox[0] = (modelbox[0] + 360) % 360 if modelbox[1] != 360: modelbox[1] = (modelbox[1] + 360) % 360 else: if p.file_input is not None: modelbox = model_data.calc_box() else: logger.error('modelbox should be provided if no model file is' 'provided') sys.exit(1) p.modelbox_calc = modelbox if p.file_input is not None: model_data.read_coordinates() # Select model data in the region modelbox model_data.len_coord = len(numpy.shape(model_data.vlon)) if p.grid == 'regular' or model_data.len_coord == 1: if modelbox[0] < modelbox[1]: _i_lon = numpy.where(((modelbox[0]-1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1]+1)))[0] else: _i_lon = numpy.where(((modelbox[0]-1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1]+1)))[0] model_data.model_index_lon = _i_lon _i_lat = numpy.where(((modelbox[2]-1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3]+1)))[0] model_data.model_index_lat = _i_lat model_data.vlon = model_data.vlon[model_data.model_index_lon] model_data.vlat = model_data.vlat[model_data.model_index_lat] else: if modelbox[0] < modelbox[1]: _i_box = numpy.where(((modelbox[0]-1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1]+1)) & ((modelbox[2]-1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3]+1))) else: _i_box = numpy.where(((modelbox[0]-1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1]+1)) & ((modelbox[2]-1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3]+1))) model_data.model_index = _i_box model_data.vlon = model_data.vlon[model_data.model_index] model_data.vlat = model_data.vlat[model_data.model_index] model_data.model = p.model model_data.vloncirc = numpy.rad2deg(numpy.unwrap(model_data.vlon)) if modelbox[1] == 0: modelbox[1] = 359.99 # - Make SWOT grid if necessary """ if p.makesgrid is True: logger.info('\n Force creation of SWOT grid') orb = build_swath.makeorbit(modelbox, p, orbitfile=p.filesat) # build swath for this orbit build_swath.orbit2swath(modelbox, p, orb) logger.info("\n SWOT Grids and nadir tracks have been written in " "{}".format(p.outdatadir)) logger.info("-----------------------------------------------") # - Initialize random coefficients that are used to compute # random errors following the specified spectrum err, errnad = load_error(p) # - Compute interpolated SSH and errors for each pass, at each # cycle logger.info('Compute interpolated SSH and errors:') # load all SWOT grid files (one for each pass) listsgridfile = sorted(glob.glob(p.filesgrid + '_p*.nc')) if not listsgridfile: logger.error('\n There is no SWOT grid file in {}, run simulator with' ' option makesgrid set to true in your params' ' file'.format(p.outdatadir)) sys.exit(1) # Build model time steps from parameter file modeltime = numpy.arange(0, p.nstep*p.timestep, p.timestep) # Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) if len(modeltime) > len(list_file): logger.error('There is not enough model files in the list of' 'files') sys.exit(1) # Initialize progress bar variables istep = 0 ntot = 1 # - Loop on SWOT grid files for sgridfile in listsgridfile: # Load SWOT grid files (Swath and nadir) sgrid = load_sgrid(sgridfile, p) sgrid.gridfile = sgridfile if p.nadir is True: ngrid = load_ngrid(sgridfile, p) ngrid.gridfile = sgridfile else: ngrid = None # Set Teval and nTeval to None to interpolate the mask once Teval = None nTeval = None # Select model data around the swath to reduce interpolation cost in # griddata # - Generate SWOT like and nadir-like data: # Compute number of cycles needed to cover all nstep model timesteps rcycle = (p.timestep * p.nstep)/float(sgrid.cycle) ncycle = int(rcycle) # Loop on all cycles for cycle in range(0, ncycle+1): if ifile > (p.nstep/p.timestep + 1): break # Create SWOT-like and Nadir-like data if not p.file_input: model_data = [] SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress, Teval, nTeval, mask_land = create_SWOTlikedata( cycle, numpy.shape(listsgridfile)[0]*rcycle, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True, Teval=Teval, nTeval=nTeval) # Save outputs in a netcdf file if (~numpy.isnan(vindice)).any() or not p.file_input: save_SWOT(cycle, sgrid, err, p, mask_land, time=time, vindice=vindice, SSH_true=SSH_true, save_var=p.save_variables) if p.nadir is True: save_Nadir(cycle, ngrid, errnad, err, p, time=time, vindice_nadir=vindice_nadir, SSH_true_nadir=SSH_true_nadir) del time # if p.file_input: del index sgrid.lon = (sgrid.lon + 360) % 360 if p.nadir is True: ngrid.lon = (ngrid.lon + 360) % 360 if p.file_input is not None: model_data.vlon = (model_data.vlon + 360) % 360 modelbox[0] = (modelbox[0] + 360) % 360 modelbox[1] = (modelbox[1] + 360) % 360 del sgrid if p.nadir is True: del ngrid if progress != 1: str1 = 'All passes have been processed' progress = mod_tools.update_progress(1, str1, '') # - Write Selected parameters in a txt file timestop = datetime.datetime.now() timestop = timestop.strftime('%Y%m%dT%H%M%SZ') timestart = timestart.strftime('%Y%m%dT%H%M%SZ') op_file = 'swot_simulator_{}_{}.output'.format(timestart, timestop) op_file = os.path.join(p.outdatadir, op_file) rw_data.write_params(p, op_file) logger.info("\n Simulated swot files have been written in {}".format( p.outdatadir)) logger.info("----------------------------------------------------------")
def create_SWOTlikedata(cycle, ntotfile, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True, Teval=None, nTeval=None): '''Create SWOT and nadir errors err and errnad, interpolate model SSH model _data on swath and nadir track, compute SWOT-like and nadir-like data for cycle, SWOT grid sgrid and ngrid. ''' # - Progress bar variables are global global istep global ntot # Initialiaze errors and SSH progress = 0 shape_sgrid = (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1]) err.karin = numpy.zeros(shape_sgrid) err.roll = numpy.zeros(shape_sgrid) err.phase = numpy.zeros(shape_sgrid) err.baseline_dilation = numpy.zeros(shape_sgrid) err.timing = numpy.zeros(shape_sgrid) err.wet_tropo1 = numpy.zeros(shape_sgrid) err.wet_tropo2 = numpy.zeros(shape_sgrid) err.ssb = numpy.zeros(shape_sgrid) err.wt = numpy.zeros(shape_sgrid) SSH_true = numpy.zeros(shape_sgrid) mask_land = numpy.zeros(shape_sgrid) # Initialize nadir variable in case the simulator is run with nadir option # at False SSH_true_nadir = 0 vindice_nadir = 0 if p.nadir is True: err.wet_tropo1nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wet_tropo2nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wtnadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice_nadir = numpy.zeros(numpy.shape(ngrid.lon)) * numpy.nan SSH_true_nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice = numpy.zeros(numpy.shape(SSH_true)) * numpy.nan # Definition of the time in the model date1 = cycle * sgrid.cycle time = sgrid.time + date1 # Look for satellite data that are beween step-p.timestep/2 and # step+p.step/2 if p.file_input: time_shift_end = time[-1] - sgrid.timeshift time_shift_start = time[0] - sgrid.timeshift model_tmin = modeltime - p.timestep/2. model_tmax = modeltime + p.timestep/2. index_filemodel = numpy.where((time_shift_end >= model_tmin) & (time_shift_start < model_tmax)) # At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: pstep = float(istep) / float(ntot * ntotfile) str1 = 'pass: {}'.format(sgrid.ipass) str2 = 'model file: {}, cycle: {}'.format(list_file[ifile], cycle + 1) progress = mod_tools.update_progress(pstep, str1, str2) # If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1] > 0: # number of file to be processed used in the progress bar ntot = ntot + numpy.shape(index_filemodel)[1] - 1 # if numpy.shape(index)[1]>1: # Select part of the track that corresponds to the time of the # model (+-timestep/2) time_shift = time - sgrid.timeshift model_tmin = modeltime[ifile] - p.timestep/2. model_tmax = modeltime[ifile] + p.timestep/2. ind_time = numpy.where((time_shift >= model_tmin) & (time_shift < model_tmax)) if p.nadir is True: time_shift = time - ngrid.timeshift ind_nadir_time = numpy.where((time_shift >= model_tmin) & (time_shift < model_tmax)) # Load data from this model file model_step_ctor = getattr(rw_data, model_data.model) nfile = os.path.join(p.indatadir, list_file[ifile]) model_step = model_step_ctor(p, nfile=nfile, var=p.var) if p.grid == 'regular' or model_data.len_coord ==1: model_step.read_var() SSH_model = model_step.vvar[model_data.model_index_lat, :] SSH_model = SSH_model[:, model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model = model_step.vvar # - Interpolate Model data on a SWOT grid and/or along the # nadir track # Handle Greenwich line lon_model = + model_data.vlon lon_grid = + sgrid.lon lon_ngrid = + ngrid.lon if numpy.max(lon_grid) > 359: lon_grid = numpy.mod(lon_grid + 180., 360.) - 180. lon_model = numpy.mod(lon_model + 180., 360.) - 180. if p.nadir is True: lon_ngrid = numpy.mod(lon_ngrid + 180., 360.) - 180. # if grid is regular, use interpolate.RectBivariateSpline to # interpolate if p.grid == 'regular' or model_data.len_coord == 1: # ########################TODO # To be moved to routine rw_data indsorted = numpy.argsort(lon_model) lon_model = lon_model[indsorted] SSH_model = SSH_model[:, indsorted] # Flatten satellite grid and select part of the track # corresponding to the model time lonswot = lon_grid[ind_time[0], :].flatten() latswot = sgrid.lat[ind_time[0], :].flatten() interp = interpolate_regular_1D _ssh, Teval = interp(p, lon_model, model_data.vlat, SSH_model, lonswot, latswot, Teval=Teval) nal, nac = numpy.shape(sgrid.lon[ind_time[0], :]) _mask_land = numpy.zeros((nal, nac)) Teval2d = Teval.reshape(nal, nac) _mask_land[Teval2d > 0] = 3 mask_land[ind_time[0], :] = _mask_land SSH_true[ind_time[0], :] = _ssh.reshape(nal, nac) if p.nadir is True: lonnadir = lon_ngrid[ind_nadir_time[0]].ravel() latnadir = ngrid.lat[ind_nadir_time[0]].ravel() _ssh, nTeval = interp(p, lon_model, model_data.vlat, SSH_model, lonnadir, latnadir, Teval=nTeval) SSH_true_nadir[ind_nadir_time[0]] = _ssh else: # Grid is irregular, interpolation can be done using # pyresample module if it is installed or griddata # function from scipy. # Note that griddata is slower than pyresample functions. try: import pyresample as pr wrap_lon = pr.utils.wrap_longitudes lon_model = wrap_lon(lon_model) lon_grid = wrap_lon(lon_grid) if model_data.len_coord <= 1: logger.error('Model grid is irregular,' 'coordinates should be in 2d') sys.exit(1) geomdef = pr.geometry.SwathDefinition swath_def = geomdef(lons=lon_model, lats=model_data.vlat) grid_def = geomdef(lons=lon_grid, lats=sgrid.lat) interp = interpolate_irregular_pyresample _ssh = interp(swath_def, SSH_model, grid_def, max(p.delta_al, p.delta_ac), interp_type=p.interpolation) mask_land[numpy.isnan(_ssh)] = 3 SSH_true[ind_time[0], :] = _ssh if p.nadir is True: lon_ngrid = wrap_lon(lon_ngrid) ngrid_def = geomdef(lons=lon_ngrid, lats=ngrid.lat) _ssh = interp(swath_def, SSH_model, ngrid_def, max(p.delta_al, p.delta_ac), interp_type=p.interpolation) SSH_true_nadir[ind_time[0]] = _ssh except ImportError: interp = interpolate.griddata model_ravel = (lon_model(), model_data.vlat.ravel()) _ssh = interp(model_ravel, SSH_model.ravel(), (lon_grid[ind_time[0], :], sgrid.lat[ind_time[0], :]), method=p.interpolation) mask_land[numpy.isnan(_ssh)] = 3 SSH_true[ind_time[0], :] = _ssh if p.nadir is True: _ssh = interp(model_ravel, SSH_model.ravel(), (lon_ngrid[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) SSH_true_nadir[ind_nadir_time[0]] = _ssh if p.interpolation == 'nearest': if modelbox[0] > modelbox[1]: ind = numpy.where(((sgrid.lon < modelbox[0]) & (sgrid.lon > modelbox[1])) | (sgrid.lat < modelbox[2]) | (sgrid.lat > modelbox[3])) SSH_true[ind] = numpy.nan if p.nadir is True: lontmp = ngrid.lon lattmp = ngrid.lat ind = numpy.where(((lontmp < modelbox[0]) & (lontmp > modelbox[1])) | (lattmp < modelbox[2]) | (lattmp > modelbox[3])) del lontmp, lattmp SSH_true_nadir[ind] = numpy.nan else: ind = numpy.where((sgrid.lon < modelbox[0]) | (sgrid.lon > modelbox[1]) | (sgrid.lat < modelbox[2]) | (sgrid.lat > modelbox[3])) SSH_true[ind] = numpy.nan if p.nadir is True: lontmp = ngrid.lon lattmp = ngrid.lat ind = numpy.where((lontmp < modelbox[0]) | (lontmp > modelbox[1]) | (lattmp < modelbox[2]) | (lattmp > modelbox[3])) del lontmp, lattmp SSH_true_nadir[ind] = numpy.nan vindice[ind_time[0], :] = ifile if p.nadir is True: vindice_nadir[ind_nadir_time[0]] = ifile del ind_time, SSH_model, model_step, ind_nadir_time else: del ind_time, SSH_model, model_step istep += ntot #1 else: istep += ntot #1 pstep = float(istep) / float(ntotfile * ntot) str1 = 'pass: {}'.format(sgrid.ipass) str2 = 'no model file provided, cycle: {}'.format(cycle + 1) progress = mod_tools.update_progress(pstep, str1, str2) err.make_error(sgrid, cycle, SSH_true, p) if p.save_variables != 'expert': err.reconstruct_2D(p, sgrid.x_ac) err.make_SSH_error(SSH_true, p) if p.nadir is True: errnad.make_error(ngrid, cycle, SSH_true_nadir, p) if p.nbeam == 1: errnad.SSH = SSH_true_nadir + errnad.nadir + err.wet_tropo1nadir else: errnad.SSH = SSH_true_nadir + errnad.nadir + err.wet_tropo2nadir # if p.file_input: del ind_time, SSH_model, model_step return SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress, \ Teval, nTeval, mask_land
def create_Nadirlikedata(cycle, ntotfile, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=False): # - Progress bar variables are global global istep global ntot global ifile errnad.wet_tropo1nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.wt = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice = numpy.zeros(numpy.shape(ngrid.lon))*numpy.nan # Definition of the time in the model date1 = cycle * ngrid.cycle time = ngrid.time + date1 # Look for satellite data that are beween step-p.timesetp/2 and # setp+p.timestep/2 if p.file_input is not None: time_shift_end = time[-1] - ngrid.timeshift time_shift_start = time[0] - ngrid.timeshift model_tmin = modeltime - p.timestep/2. model_tmax = modeltime + p.timestep/2. index_filemodel = numpy.where((time_shift_end >= model_tmin) & (time_shift_start < model_tmax)) # [0] # At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: if progress_bar: pstep = float(istep) / float(ntot) str1 = 'orbit: {}'.format(ngrid.ipass) str2 = 'model file: {}, cycle: {}'.format(list_file[ifile], cycle + 1) progress = mod_tools.update_progress(pstep, str1, str2) else: progress = None # If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1] > 0: ntot = ntot + numpy.shape(index_filemodel)[1] - 1 time_shift = (time - ngrid.timeshift) model_min = modeltime[ifile] - p.timestep/2. model_max = modeltime[ifile] + p.timestep/2. ind_nadir_time = numpy.where((time_shift >= model_min) & (time_shift < model_max)) if len(ind_nadir_time[0]) < 3: continue model_step_ctor = getattr(rw_data, model_data.model) nfile = os.path.join(p.indatadir, list_file[ifile]) model_step = model_step_ctor(p, nfile=nfile, var=p.var, time=filetime) if p.grid == 'regular' or model_data.len_coord == 1: model_step.read_var() SSH_model = model_step.vvar[model_data.model_index_lat, :] SSH_model = SSH_model[:, model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model = model_step.vvar # - Interpolate Model data along the nadir # track # Handle Greenwich line lon_model = + model_data.vlon lon_ngrid = + ngrid.lon if numpy.max(lon_ngrid) > 359: lon_ngrid = numpy.mod(lon_ngrid + 180., 360.) - 180. lon_model = numpy.mod(lon_model + 180., 360.) - 180. # if grid is regular, use interpolate.RectBivariateSpline to # interpolate if p.grid == 'regular' or model_data.len_coord == 1: # ########################TODO # To be moved to routine rw_data indsorted = numpy.argsort(model_data.vlon) model_data.vlon = model_data.vlon[indsorted] SSH_model = SSH_model[:, indsorted] interp = interpolate_regular_1D _ssh, Teval = interp(p, model_data.vlon, model_data.vlat, SSH_model, ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel(), Teval=None) SSH_true_nadir[ind_nadir_time[0]] = _ssh else: # Grid is irregular, interpolation can be done using pyresample # module if it is installed or griddata function from scipy. # Note that griddata is slower than pyresample functions. try: import pyresample as pr ngrid.lon = pr.utils.wrap_longitudes(ngrid.lon) model_data.vlon = pr.utils.wrap_longitudes(model_data.vlon) geomdef = pr.geometry.SwathDefinition ngrid_def = geomdef(lons=ngrid.lon[ind_nadir_time[0]], lats=ngrid.lat[ind_nadir_time[0]]) swath_def = geomdef(lons=model_data.vlon, lats=model_data.vlat) interp = interpolate_irregular_pyresample _ssh = interp(swath_def, SSH_model, ngrid_def, p.delta_al, interp_type=p.interpolation) SSH_true_nadir[ind_nadir_time[0]] = _ssh except ImportError: interp = interpolate.griddata _ssh = interp((model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) SSH_true_nadir[ind_nadir_time[0]] = _ssh if p.interpolation == 'nearest': if modelbox[0] > modelbox[1]: ind = numpy.where(((ngrid.lon < modelbox[0]) & (ngrid.lon > modelbox[1])) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3])) else: ind = numpy.where((ngrid.lon < modelbox[0]) | (ngrid.lon > modelbox[1]) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3])) SSH_true_nadir[ind] = numpy.nan vindice[ind_nadir_time[0]] = ifile istep += 1 else: if progress_bar: pstep = float(istep) / float(ntotfile * ntot) str1 = 'orbit: {}'.format(ngrid.ipass) cy1 = cycle + 1 str2 = 'model file: {}, cycle: {}'.format(list_file[ifile], cy1) progress = mod_tools.update_progress(pstep, str1, str2) else: progress = None istep += 1 errnad.make_error(ngrid, cycle, SSH_true_nadir, p) # , ind[0]) errnad.SSH = SSH_true_nadir + errnad.nadir + errnad.wet_tropo1nadir # del SSH_model, model_step, ind_nadir_time return SSH_true_nadir, vindice, time, progress
def orbit2swath(modelbox, p,orb): # -- Load altimeter orbit npoints=1 x_al=orb.x_al stime=orb.time lon=orb.lon lat=orb.lat tcycle=orb.cycle al_cycle=orb.al_cycle passtime=orb.passtime ## -- Compute accross track distances from nadir # Number of points in half of the swath nhalfswath=int( (p.halfswath-p.halfgap)/p.delta_ac) +1 # Across track distance from nadir x_ac=numpy.zeros((2*nhalfswath)) for i in range(0, int(nhalfswath)): x_ac[i]=-(nhalfswath-i)*p.delta_ac-p.halfgap+p.delta_ac x_ac[i+nhalfswath]=i*p.delta_ac+p.halfgap ## -- Computation of SWOT grid and storage by passes print('\n Compute SWOT grid') # Detect first pass that is in the subdomain ipass0=0 strpass=[] # Loop on all passes after the first pass detected for ipass in range(ipass0,numpy.shape(passtime)[0]): # Detect indices corresponding to the pass if ipass==numpy.shape(passtime)[0]-1: ind=numpy.where((stime>=passtime[ipass]))[0] else: ind=numpy.where((stime>=passtime[ipass]) & (stime<passtime[ipass+1]))[0] nind=numpy.shape(ind)[0] # Compute swath grid if pass is in the subdomain if nind>5: mod_tools.update_progress(float(ipass+1)/float(numpy.shape(passtime)[0]), 'selected pass: '******'_p'+str(ipass+1).zfill(3)+'.nc' sgrid=rw_data.Sat_SWOT(file=filesgrid) sgrid.x_al=x_al[ind] sgrid.x_ac=x_ac sgrid.cycle=tcycle sgrid.al_cycle=al_cycle sgrid.time=stime[ind] sgrid.lon=numpy.zeros((nind,2*nhalfswath)) sgrid.lat=numpy.zeros((nind,2*nhalfswath)) SatDir=numpy.zeros((int(nind/npoints),3)) SatLoc=numpy.zeros((int((nind)/npoints),3)) # Initialize Nadir track, grid variables filengrid=p.filesgrid+'nadir_p'+str(ipass+1).zfill(3)+'.nc' ngrid=rw_data.Sat_nadir(file=filengrid) ngrid.x_al=x_al[ind] ngrid.cycle=tcycle ngrid.al_cycle=al_cycle ngrid.time=stime[ind] ## Project in cartesian coordinates satellite ground location #SatLoc[:,0], SatLoc[:,1], SatLoc[:,2]=mod_tools.spher2cart(lon[ind[0]:ind[-1]+npoints:npoints], lat[ind[0]:ind[-1]+npoints:npoints]) #if numpy.min(lon[ind[0]:ind[-1]+1])<1. and numpy.max(lon[ind[0]:ind[-1]+1])>359.: #lontmp=lon[ind[0]:ind[-1]+1] #lontmp[numpy.where(lontmp>180.)]=lontmp[numpy.where(lontmp>180.)]-360. SatLoc[:,0], SatLoc[:,1], SatLoc[:,2]=mod_tools.spher2cart(lon[ind[0]:ind[-1]+1:npoints], lat[ind[0]:ind[-1]+1:npoints]) ## Compute satellite direction (SatLoc is periodic) SatDir[1:-1,0]=(SatLoc[2:,0]-SatLoc[:-2,0])/numpy.sqrt(SatLoc[1:-1,0]**2+SatLoc[1:-1,1]**2+SatLoc[1:-1,2]**2) SatDir[1:-1,1]=(SatLoc[2:,1]-SatLoc[:-2,1])/numpy.sqrt(SatLoc[1:-1,0]**2+SatLoc[1:-1,1]**2+SatLoc[1:-1,2]**2) SatDir[1:-1,2]=(SatLoc[2:,2]-SatLoc[:-2,2])/numpy.sqrt(SatLoc[1:-1,0]**2+SatLoc[1:-1,1]**2+SatLoc[1:-1,2]**2) SatDir[-1]=SatDir[-2] SatDir[0]=SatDir[1] ## Rotate from earth center around satellite direction to compute swath points of angles between the borders of the swath in left and right swath for i in range(0, nind, npoints): for j in range(0, int(nhalfswath)): R=mod_tools.rotationmat3D(float((j*p.delta_ac + p.halfgap)/(const.Rearth*10**-3)) , SatDir[int(i/npoints),:]) ObsLoc=numpy.dot(R,SatLoc[int(i/npoints)]) sgrid.lon[i,nhalfswath+j], sgrid.lat[i, nhalfswath+j]=mod_tools.cart2spher(ObsLoc[0], ObsLoc[1], ObsLoc[2]) ObsLoc=numpy.dot(numpy.transpose(R),SatLoc[int(i/npoints)]) sgrid.lon[i,nhalfswath-j-1], sgrid.lat[i, nhalfswath-j-1]=mod_tools.cart2spher(ObsLoc[0], ObsLoc[1], ObsLoc[2]) if npoints>p.delta_al: if i>=npoints: sgrid.lon[i-npoints:i, nhalfswath+j]=numpy.arange(sgrid.lon[i-npoints,nhalfswath+j], sgrid.lon[i,nhalfswath+j], (sgrid.lon[i,nhalfswath+j]-sgrid.lon[i-npoints,nhalfswath+j])/npoints) sgrid.lat[i-npoints:i,nhalfswath+j]=numpy.arange(sgrid.lat[i-npoints,nhalfswath+j], sgrid.lat[i,nhalfswath+j], (sgrid.lat[i,nhalfswath+j]-sgrid.lat[i-npoints,nhalfswath+j])/npoints) #if npoints>p.delta_al: #print 'interp not coded' #for j in range(0, 2*int(nhalfswath+1)): #sgrid.lon[:,j]=numpy.arange(sgrid.lon[0,j], sgrid.lon[ind[-1],j], (sgrid.lon[-1,j]-sgrid.lon[0,j])/npoints) #sgrid.lat[:,j]=numpy.arange(sgrid.lat[0,j], sgrid.lat[-1,j], (sgrid.lat[-1,j]-sgrid.lat[0,j])/npoints) sgrid.timeshift=orb.timeshift ngrid.timeshift=orb.timeshift ngrid.lon=(lon[ind]+360)%360 ngrid.lat=lat[ind] sgrid.lon_nadir=(lon[ind]+360)%360 sgrid.lat_nadir=lat[ind] if os.path.exists(filesgrid): os.remove(filesgrid) sgrid.write_swath() if p.nadir: if os.path.exists(filengrid): os.remove(filengrid) ngrid.write_orb() mod_tools.update_progress(1, 'All swaths have been processed', ' ') return None
def makeorbit(modelbox, p, orbitfile='orbit_292.txt', filealtimeter=None): '''Computes the orbit nadir on a subdomain. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Along track sampling, along track resolution). \n Outputs are Sat_Nadir object containing Nadir track (along track distance x_al, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time, time shfit and time of pass passtime''' # npoints = 1 # - Load SWOT orbit ground track logger.info('Load data from orbit file') if p.order_orbit_col is None: volon, volat, votime = numpy.loadtxt(orbitfile, usecols=(1, 2, 0), comments='#', unpack=True) else: ncols = p.order_orbit_col volon, volat, votime = numpy.loadtxt(orbitfile, usecols=ncols, comments='#', unpack=True) votime *= const.secinday if (volon > 360).any() or (numpy.abs(volat) > 90).any(): logger.error('Error in orbit file or wrong order of column \n' 'Columns should be in the following order' '(time, lon, lat)') sys.exit(1) dic_sat = {} with open(orbitfile, 'r') as fh: for i, line in enumerate(fh): if line.strip().startswith('#'): key, value = line.strip().split('=') dic_sat[key[1:].strip()] = float(value.strip()) else: break if 'cycle' in dic_sat.keys() and 'elevation' in dic_sat.keys(): p.satcycle = dic_sat['cycle'] p.sat_elev = dic_sat['elevation'] # - If orbit is at low resolution, interpolate at 0.5 s resolution # nop = numpy.shape(votime)[0] # tcycle = votime[nop-1] + votime[1] - votime[0] if numpy.mean(votime[1:] - votime[:-1]) > 0.5: x, y, z = mod_tools.spher2cart(volon, volat) time_hr = numpy.arange(0., votime[-1], 0.5) f = interpolate.interp1d(votime, x) x_hr = f(time_hr) f = interpolate.interp1d(votime, y) y_hr = f(time_hr) f = interpolate.interp1d(votime, z) z_hr = f(time_hr) lon_hr = numpy.zeros(len(x_hr)) + numpy.nan lat_hr = numpy.zeros(len(x_hr)) + numpy.nan lon_hr, lat_hr = mod_tools.cart2sphervect(x_hr, y_hr, z_hr) # Cut orbit if more than an orbit cycle if p.satcycle is None: p.satcycle = const.tcycle time_hr = time_hr / const.secinday ind = numpy.where((time_hr < p.satcycle)) volon = lon_hr[ind] volat = lat_hr[ind] votime = time_hr[ind] # - Get number of points in orbit nop = numpy.shape(votime)[0] # - Get cycle period. tcycle = votime[nop - 1] + votime[1] - votime[0] # shift time if the user needs to shift the time of the orbit if p.shift_time is not None: shift_index = numpy.where(votime >= p.shift_time)[0] volon = numpy.hstack([volon[shift_index[0]:], volon[:shift_index[0]]]) volat = numpy.hstack([volat[shift_index[0]:], volat[:shift_index[0]]]) # shift lon if the user needs to shift the localisation of the orbit if p.shift_lon is not None: volon = volon + p.shift_lon volon = (volon + 360) % 360 # - Rearrange orbit starting from pass 1 # Detect the beginning of pass 1 in orbit txt file. By definition, it is # the first passage at southernmost latitude. dlat = numpy.roll(volat, 1) - volat ind = numpy.where((dlat < 0) & (numpy.roll(dlat, 1) >= 0)) # Shift coordinates, so that the first point of the orbit is the beginning # of pass 1 decal = ind[0][-1] # timeshift = votime[-1] - votime[decal] volon = numpy.hstack([volon[decal:], volon[:decal]]) volat = numpy.hstack([volat[decal:], volat[:decal]]) votime = numpy.hstack([votime[decal:], votime[:decal]]) votime = (votime - votime[0]) % tcycle if votime[numpy.where(votime < 0)]: logger.warn('WARNING: there are negative times in your orbit') del ind # Compute the initial time of each pass dlat = numpy.roll(volat, 1) - volat ind = numpy.where(((dlat < 0) & (numpy.roll(dlat, 1) >= 0)) | ((dlat > 0) & (numpy.roll(dlat, 1) <= 0))) # index=numpy.hstack([0,ind[0]-1]) index = ind[0] passtime = votime[index] # Times of pass # - Compute accumulated along-track distance, longitude, latitude # in the subdomain chosen by the user or given by the model # Extract points in the domain and count the number of points (nop) in the # subdomain # modelbox=[lonmin lonmax latmin latmax] add margin around the domain # plus one point to compute Satdir matnpbox = numpy.zeros((nop)) halfswath = getattr(p, 'halfswath', 1) if modelbox[0] > modelbox[1]: matnpbox[numpy.where( (((modelbox[0] - halfswath / (const.deg2km * math.cos(modelbox[2] * math.pi / 180.)) ) <= volon) | (volon <= (modelbox[1] + halfswath / (const.deg2km * math.cos(modelbox[3] * math.pi / 180.))))) & ((modelbox[2] - halfswath / const.deg2km) <= volat) & ((modelbox[3] + halfswath / const.deg2km) >= volat))] = 1 else: matnpbox[numpy.where( ((modelbox[0] - halfswath / (const.deg2km * math.cos(modelbox[2] * math.pi / 180.))) <= volon ) & (volon <= (modelbox[1] + halfswath / (const.deg2km * math.cos(modelbox[3] * math.pi / 180.)))) & ((modelbox[2] - halfswath / const.deg2km) <= volat) & ((modelbox[3] + halfswath / const.deg2km) >= volat))] = 1 norp = int(numpy.sum(matnpbox)) # Initialize total distance travelled by the satellite since the first # point of the cycle in the subdomain at low (orbital file) resolution x_al_lr = numpy.zeros((norp)) lon_lr = numpy.zeros((norp)) lat_lr = numpy.zeros((norp)) stime_lr = numpy.zeros((norp)) # Initialize vector with accumulated distance travelled by the satellite indp = 0 distance = numpy.zeros((nop)) # Compute and store distances and coordinates that are in the defined # subdomain logger.info('Compute nadir coordinate in the new domain') for i in range(0, nop - 1): if p.progress_bar is True: mod_tools.update_progress(float(i) / float(nop - 1), None, None) if abs(volon[i + 1] - volon[i]) > 1: if volon[i + 1] > 180.: volon[i + 1] = volon[i + 1] - 360 if volon[i] > 180.: volon[i] = volon[i] - 360 distance[i + 1] = ( distance[i] + numpy.sqrt(((volon[i + 1] - volon[i]) * const.deg2km * numpy.cos(volat[i + 1] * 2 * math.pi / 360.))**2 + ((volat[i + 1] - volat[i]) * const.deg2km)**2)) volon[i + 1] = (volon[i + 1] + 360) % 360 if matnpbox[i]: x_al_lr[indp] = distance[i] lon_lr[indp] = (volon[i] + 360) % 360 lat_lr[indp] = volat[i] stime_lr[indp] = votime[i] indp += 1 # - Interpolate orbit at delta_al km resolution (default is delta_al=1) # Detect gap in time in stime (to detect step in x_al, lon and lat) dstime = stime_lr[:] - numpy.roll(stime_lr[:], 1) ind = numpy.where(dstime > 3 * (votime[1] - votime[0])) index = numpy.hstack([0, ind[0]]) nindex = numpy.shape(index)[0] # Initialize along track distance, time and coordinates at delta_al # resolution if nindex > 1: dgap = numpy.zeros((nindex)) for i in range(1, nindex): dgap[i] = x_al_lr[index[i]] - x_al_lr[max(index[i] - 1, 0)] Ninterp = (int( (x_al_lr[-1] - x_al_lr[0] - sum(dgap)) / float(p.delta_al)) + 1) x_al = numpy.zeros((Ninterp)) stime = numpy.zeros((Ninterp)) lon = numpy.zeros((Ninterp)) lat = numpy.zeros((Ninterp)) imin = 0 imax = 0 for i in range(0, nindex - 1): imax = imin + int((x_al_lr[index[i + 1] - 1] - x_al_lr[index[i]]) / float(p.delta_al)) + 1 if imax <= (imin + 1): x_al[imin] = x_al_lr[index[i]] stime[imin] = stime_lr[index[i]] lon[imin] = lon_lr[index[i]] lat[imin] = lat_lr[index[i]] else: slicei = slice(index[i], index[i + 1]) x_al[imin:imax] = numpy.arange(x_al_lr[index[i]], x_al_lr[index[i + 1] - 1], p.delta_al) stime[imin:imax] = numpy.interp(x_al[imin:imax], x_al_lr[slicei], stime_lr[slicei]) loncirc = numpy.rad2deg( numpy.unwrap(numpy.deg2rad(lon_lr[slicei]))) # if numpy.min(lon_lr[index[i]:index[i+1]])<1. # and numpy.max(lon_lr[index[i]:index[i+1]])>359.: # lontmp=lon_lr[index[i]:index[i+1]] # lontmp[numpy.where(lontmp>180.)]=lontmp[numpy.where( # lontmp>180.)]-360. # lon[imin:imax]=numpy.interp(x_al[imin:imax], # x_al_lr[index[i]:index[i+1]], lontmp) # lon[imin:imax]=(lon[imin:imax]+360)%360 # else: # lon[imin:imax]=numpy.interp(x_al[imin:imax], # x_al_lr[index[i]:index[i+1]], lon_lr[index[i]:index[i+1]]) lon[imin:imax] = numpy.interp(x_al[imin:imax], x_al_lr[slicei], loncirc) lat[imin:imax] = numpy.interp(x_al[imin:imax], x_al_lr[slicei], lat_lr[slicei]) imin = imax x_al[imin:] = numpy.arange( x_al_lr[index[-1]], x_al_lr[index[-1]] + (Ninterp - imin) * p.delta_al, p.delta_al) stime[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], stime_lr[index[-1]:]) loncirc = numpy.rad2deg(numpy.unwrap(numpy.deg2rad( lon_lr[index[-1]:]))) lon[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], loncirc) lat[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], lat_lr[index[-1]:]) else: Ninterp = int((x_al_lr[-2] - x_al_lr[0]) / float(p.delta_al)) + 1 x_al = numpy.zeros((Ninterp)) stime = numpy.zeros((Ninterp)) lon = numpy.zeros((Ninterp)) lat = numpy.zeros((Ninterp)) x_al = numpy.arange(x_al_lr[0], x_al_lr[-2], p.delta_al) stime = numpy.interp(x_al, x_al_lr[:-1], stime_lr[:-1]) loncirc = numpy.rad2deg(numpy.unwrap(numpy.deg2rad(lon_lr[:-1]))) lon = numpy.interp(x_al, x_al_lr[:-1], loncirc) lat = numpy.interp(x_al, x_al_lr[:-1], lat_lr[:-1]) lon = lon % 360 nfile = '{}.nc'.format(orbitfile[:-4]) orb = rw_data.Sat_nadir(nfile=nfile) orb.x_al = x_al orb.time = stime orb.lon = lon orb.lat = lat orb.cycle = tcycle orb.al_cycle = distance[-1] orb.passtime = numpy.sort(passtime) orb.timeshift = p.timeshift orb.sat_elev = p.sat_elev return orb
def makeorbit(modelbox, p, orbitfile='orbit_292.txt', filealtimeter=None): '''Computes the orbit nadir on a subdomain. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Along track sampling, along track resolution). \n Outputs are Sat_Nadir object containing Nadir track (along track distance x_al, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time, time shfit and time of pass passtime''' # npoints = 1 # - Load SWOT orbit ground track logger.info('Load data from orbit file') if p.order_orbit_col is None: volon, volat, votime = numpy.loadtxt(orbitfile, usecols=(1, 2, 0), comments='#', unpack=True) else: ncols = p.order_orbit_col volon, volat, votime = numpy.loadtxt(orbitfile, usecols=ncols, comments='#', unpack=True) votime *= const.secinday if (volon > 360).any() or (numpy.abs(volat) > 90).any(): logger.error('Error in orbit file or wrong order of column \n' 'Columns should be in the following order' '(time, lon, lat)') sys.exit(1) dic_sat = {} with open(orbitfile, 'r') as fh: for i, line in enumerate(fh): if line.strip().startswith('#'): key, value = line.strip().split('=') dic_sat[key[1:].strip()] = float(value.strip()) else: break if 'cycle' in dic_sat.keys() and 'elevation' in dic_sat.keys(): p.satcycle = dic_sat['cycle'] p.sat_elev = dic_sat['elevation'] # - If orbit is at low resolution, interpolate at 0.5 s resolution # nop = numpy.shape(votime)[0] # tcycle = votime[nop-1] + votime[1] - votime[0] if numpy.mean(votime[1:] - votime[:-1]) > 0.5: x, y, z = mod_tools.spher2cart(volon, volat) time_hr = numpy.arange(0., votime[-1], 0.5) f = interpolate.interp1d(votime, x) x_hr = f(time_hr) f = interpolate.interp1d(votime, y) y_hr = f(time_hr) f = interpolate.interp1d(votime, z) z_hr = f(time_hr) lon_hr = numpy.zeros(len(x_hr)) + numpy.nan lat_hr = numpy.zeros(len(x_hr)) + numpy.nan lon_hr, lat_hr = mod_tools.cart2sphervect(x_hr, y_hr, z_hr) # Cut orbit if more than an orbit cycle if p.satcycle is None: p.satcycle = const.tcycle time_hr = time_hr / const.secinday ind = numpy.where((time_hr < p.satcycle)) volon = lon_hr[ind] volat = lat_hr[ind] votime = time_hr[ind] # - Get number of points in orbit nop = numpy.shape(votime)[0] # - Get cycle period. tcycle = votime[nop-1] + votime[1] - votime[0] # shift time if the user needs to shift the time of the orbit if p.shift_time is not None: shift_index = numpy.where(votime >= p.shift_time)[0] volon = numpy.hstack([volon[shift_index[0]:], volon[:shift_index[0]]]) volat = numpy.hstack([volat[shift_index[0]:], volat[:shift_index[0]]]) # shift lon if the user needs to shift the localisation of the orbit if p.shift_lon is not None: volon = volon + p.shift_lon volon = (volon + 360) % 360 # - Rearrange orbit starting from pass 1 # Detect the beginning of pass 1 in orbit txt file. By definition, it is # the first passage at southernmost latitude. dlat = numpy.roll(volat, 1) - volat ind = numpy.where((dlat < 0) & (numpy.roll(dlat, 1) >= 0)) # Shift coordinates, so that the first point of the orbit is the beginning # of pass 1 decal = ind[0][-1] # timeshift = votime[-1] - votime[decal] volon = numpy.hstack([volon[decal:], volon[:decal]]) volat = numpy.hstack([volat[decal:], volat[:decal]]) votime = numpy.hstack([votime[decal:], votime[:decal]]) votime = (votime - votime[0]) % tcycle if votime[numpy.where(votime < 0)]: logger.warn('WARNING: there are negative times in your orbit') del ind # Compute the initial time of each pass dlat = numpy.roll(volat, 1) - volat ind = numpy.where(((dlat < 0) & (numpy.roll(dlat, 1) >= 0)) | ((dlat > 0) & (numpy.roll(dlat, 1) <= 0))) # index=numpy.hstack([0,ind[0]-1]) index = ind[0] passtime = votime[index] # Times of pass # - Compute accumulated along-track distance, longitude, latitude # in the subdomain chosen by the user or given by the model # Extract points in the domain and count the number of points (nop) in the # subdomain # modelbox=[lonmin lonmax latmin latmax] add margin around the domain # plus one point to compute Satdir matnpbox = numpy.zeros((nop)) halfswath = getattr(p, 'halfswath', 1) if modelbox[0] > modelbox[1]: matnpbox[numpy.where((((modelbox[0] - halfswath / (const.deg2km * math.cos(modelbox[2]*math.pi/180.))) <= volon) | (volon <= (modelbox[1] + halfswath/(const.deg2km * math.cos(modelbox[3]*math.pi/180.))))) & ((modelbox[2] - halfswath/const.deg2km) <= volat) & ((modelbox[3] + halfswath/const.deg2km) >= volat))] = 1 else: matnpbox[numpy.where(((modelbox[0] - halfswath / (const.deg2km * math.cos(modelbox[2]*math.pi/180.))) <= volon) & (volon <= (modelbox[1] + halfswath/(const.deg2km * math.cos(modelbox[3]*math.pi/180.)))) & ((modelbox[2] - halfswath/const.deg2km) <= volat) & ((modelbox[3] + halfswath/const.deg2km) >= volat))] = 1 norp = int(numpy.sum(matnpbox)) # Initialize total distance travelled by the satellite since the first # point of the cycle in the subdomain at low (orbital file) resolution x_al_lr = numpy.zeros((norp)) lon_lr = numpy.zeros((norp)) lat_lr = numpy.zeros((norp)) stime_lr = numpy.zeros((norp)) # Initialize vector with accumulated distance travelled by the satellite indp = 0 distance = numpy.zeros((nop)) # Compute and store distances and coordinates that are in the defined # subdomain logger.info('Compute nadir coordinate in the new domain') for i in range(0, nop - 1): if p.progress_bar is True: mod_tools.update_progress(float(i) / float(nop-1), None, None) if abs(volon[i + 1] - volon[i]) > 1: if volon[i + 1] > 180.: volon[i + 1] = volon[i + 1] - 360 if volon[i] > 180.: volon[i] = volon[i] - 360 distance[i+1] = (distance[i] + numpy.sqrt(((volon[i+1]-volon[i]) * const.deg2km*numpy.cos(volat[i+1] * 2*math.pi/360.))**2 + ((volat[i+1] - volat[i]) * const.deg2km)**2)) volon[i + 1] = (volon[i + 1] + 360) % 360 if matnpbox[i]: x_al_lr[indp] = distance[i] lon_lr[indp] = (volon[i] + 360) % 360 lat_lr[indp] = volat[i] stime_lr[indp] = votime[i] indp += 1 # - Interpolate orbit at delta_al km resolution (default is delta_al=1) # Detect gap in time in stime (to detect step in x_al, lon and lat) dstime = stime_lr[:] - numpy.roll(stime_lr[:], 1) ind = numpy.where(dstime > 3*(votime[1] - votime[0])) index = numpy.hstack([0, ind[0]]) nindex = numpy.shape(index)[0] # Initialize along track distance, time and coordinates at delta_al # resolution if nindex > 1: dgap = numpy.zeros((nindex)) for i in range(1, nindex): dgap[i] = x_al_lr[index[i]] - x_al_lr[max(index[i] - 1, 0)] Ninterp = (int((x_al_lr[-1] - x_al_lr[0] - sum(dgap)) / float(p.delta_al)) + 1) x_al = numpy.zeros((Ninterp)) stime = numpy.zeros((Ninterp)) lon = numpy.zeros((Ninterp)) lat = numpy.zeros((Ninterp)) imin = 0 imax = 0 for i in range(0, nindex - 1): imax = imin + int((x_al_lr[index[i+1]-1] - x_al_lr[index[i]]) / float(p.delta_al)) + 1 if imax <= (imin + 1): x_al[imin] = x_al_lr[index[i]] stime[imin] = stime_lr[index[i]] lon[imin] = lon_lr[index[i]] lat[imin] = lat_lr[index[i]] else: slicei = slice(index[i], index[i + 1]) x_al[imin: imax] = numpy.arange(x_al_lr[index[i]], x_al_lr[index[i+1] - 1], p.delta_al) stime[imin: imax] = numpy.interp(x_al[imin: imax], x_al_lr[slicei], stime_lr[slicei]) loncirc = numpy.rad2deg(numpy.unwrap(numpy.deg2rad( lon_lr[slicei]))) # if numpy.min(lon_lr[index[i]:index[i+1]])<1. # and numpy.max(lon_lr[index[i]:index[i+1]])>359.: # lontmp=lon_lr[index[i]:index[i+1]] # lontmp[numpy.where(lontmp>180.)]=lontmp[numpy.where( # lontmp>180.)]-360. # lon[imin:imax]=numpy.interp(x_al[imin:imax], # x_al_lr[index[i]:index[i+1]], lontmp) # lon[imin:imax]=(lon[imin:imax]+360)%360 # else: # lon[imin:imax]=numpy.interp(x_al[imin:imax], # x_al_lr[index[i]:index[i+1]], lon_lr[index[i]:index[i+1]]) lon[imin: imax] = numpy.interp(x_al[imin: imax], x_al_lr[slicei], loncirc) lat[imin: imax] = numpy.interp(x_al[imin: imax], x_al_lr[slicei], lat_lr[slicei]) imin = imax x_al[imin:] = numpy.arange(x_al_lr[index[-1]], x_al_lr[index[-1]] + (Ninterp - imin)*p.delta_al, p.delta_al) stime[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], stime_lr[index[-1]:]) loncirc = numpy.rad2deg(numpy.unwrap(numpy.deg2rad( lon_lr[index[-1]:]))) lon[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], loncirc) lat[imin:] = numpy.interp(x_al[imin:], x_al_lr[index[-1]:], lat_lr[index[-1]:]) else: Ninterp = int((x_al_lr[-2] - x_al_lr[0]) / float(p.delta_al)) + 1 x_al = numpy.zeros((Ninterp)) stime = numpy.zeros((Ninterp)) lon = numpy.zeros((Ninterp)) lat = numpy.zeros((Ninterp)) x_al = numpy.arange(x_al_lr[0], x_al_lr[-2], p.delta_al) stime = numpy.interp(x_al, x_al_lr[:-1], stime_lr[:-1]) loncirc = numpy.rad2deg(numpy.unwrap(numpy.deg2rad(lon_lr[:-1]))) lon = numpy.interp(x_al, x_al_lr[:-1], loncirc) lat = numpy.interp(x_al, x_al_lr[:-1], lat_lr[:-1]) lon = lon % 360 nfile = '{}.nc'.format(orbitfile[:-4]) orb = rw_data.Sat_nadir(nfile=nfile) orb.x_al = x_al orb.time = stime orb.lon = lon orb.lat = lat orb.cycle = tcycle orb.al_cycle = distance[-1] orb.passtime = numpy.sort(passtime) orb.timeshift = p.timeshift orb.sat_elev = p.sat_elev return orb
def run_simulator(file_param): import swotsimulator.build_swath as build_swath import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Initialize some parameters values try: p.shift_lon=p.shift_lon except: p.shift_lon=None try: p.shift_time=p.shift_time except: p.shift_time=None try: model=p.model except: model='NETCDF_MODEL'; p.model= model try: p.model_nan=p.model_nan except: p.model_nan=0. try: p.SSH_factor=p.SSH_factor except: p.SSH_factor=1. #; p.SSH_factor=SSH_factor try: p.nadir=p.nadir except: p.nadir=True try: p.grid=p.grid except: p.grid='regular' ## - Progress bar variables are global global istep global ntot ## - Read list of user model files """ if p.file_input: list_file = [line.strip() for line in open(p.file_input)] ## - Read model input coordinates ''' # if no modelbox is specified (modelbox=None), the domain of the input data is taken as a modelbox # coordinates from the region defined by modelbox are selected if p.file_input: model_data=eval('rw_data.'+model+'(file=p.indatadir+os.sep+list_file[0])') if p.modelbox: modelbox=numpy.array(p.modelbox, dtype='float') ## Use convert to 360 data modelbox[0]=(modelbox[0]+360)%360 if modelbox[1] != 360: modelbox[1]=(modelbox[1]+360)%360 else: if p.file_input: modelbox=model_data.calc_box() else: print('modelbox should be provided if no model file is provided') sys.exit() if p.file_input: model_data.read_coordinates() ## Select model data in the region modelbox if p.grid=='regular': if modelbox[0]<modelbox[1]: model_data.model_index_lon=numpy.where(((modelbox[0]-1)<=model_data.vlon) & (model_data.vlon<=(modelbox[1]+1)))[0] else: model_data.model_index_lon=numpy.where(((modelbox[0]-1)<=model_data.vlon) | (model_data.vlon<=(modelbox[1]+1)))[0] model_data.model_index_lat=numpy.where(((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))[0] model_data.vlon=model_data.vlon[model_data.model_index_lon] model_data.vlat=model_data.vlat[model_data.model_index_lat] else: if modelbox[0]<modelbox[1]: model_data.model_index=numpy.where(((modelbox[0]-1)<=model_data.vlon) & (model_data.vlon<=(modelbox[1]+1)) & ((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))#[0] else: model_data.model_index=numpy.where(((modelbox[0]-1)<=model_data.vlon) | (model_data.vlon<=(modelbox[1]+1)) & ((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))#[0] model_data.model=model model_data.vloncirc=numpy.rad2deg(numpy.unwrap(model_data.vlon)) if modelbox[1]==0: modelbox[1]=359.99 ## - Make SWOT grid if necessary """ if p.makesgrid: print('\n Force creation of SWOT grid') orb=build_swath.makeorbit(modelbox, p, orbitfile=p.filesat) build_swath.orbit2swath(modelbox, p, orb) print("\n SWOT Grids and nadir tracks have been written in "+ p.outdatadir ) print("-----------------------------------------------") ## - Initialize random coefficients that are used to compute ## random errors following the specified spectrum err, errnad=load_error(p) ## - Compute interpolated SSH and errors for each pass, at each ## cycle print('Compute interpolated SSH and errors:') ## load all SWOT grid files (one for each pass) listsgridfile = sorted(glob.glob(p.filesgrid+'_p*.nc')) if not listsgridfile: print('\n There is no SWOT grid file in '+p.outdatadir+ ', run simulator with option makesgrid set to true in your params file' ) sys.exit() ## Model time step modeltime=numpy.arange(0,p.nstep*p.timestep, p.timestep) ## Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) ## Initialize progress bar variables istep=0; ntot=1 ## - Loop on SWOT grid files for sgridfile in listsgridfile: ## Load SWOT grid files (Swath and nadir) sgrid=load_sgrid(sgridfile, p) sgrid.gridfile=sgridfile if p.nadir: ngrid=load_ngrid(sgridfile, p) ngrid.gridfile=sgridfile ## Select model data around the swath to reduce interpolation cost in griddata ## - Generate SWOT like and nadir-like data: ## Compute number of cycles needed to cover all nstep model timesteps rcycle=(p.timestep*p.nstep)/float(sgrid.cycle) ncycle=int(rcycle) ## Loop on all cycles for cycle in range(0,ncycle+1): if ifile>(p.nstep/p.timestep +1): break ## Create SWOT-like and Nadir-like data if not p.file_input : model_data=[] SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress=create_SWOTlikedata(cycle, numpy.shape(listsgridfile)[0]*rcycle, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True) #SSH_true_nadir, vindice_nadir=create_Nadirlikedata(cycle, sgrid, ngrid, model_data, modeltime, err, errnad, p) ## Save outputs in a netcdf file if (~numpy.isnan(vindice)).any() or not p.file_input: save_SWOT(cycle, sgrid, err, p, time=time, vindice=vindice, SSH_true=SSH_true) if p.nadir: save_Nadir(cycle, ngrid, errnad, err , p,time=time, vindice_nadir=vindice_nadir, SSH_true_nadir=SSH_true_nadir) del time #if p.file_input: del index sgrid.lon=(sgrid.lon+360)%360 ngrid.lon=(ngrid.lon+360)%360 if p.file_input: model_data.vlon=(model_data.vlon+360)%360 modelbox[0]=(modelbox[0]+360)%360 modelbox[1]=(modelbox[1]+360)%360 del sgrid, ngrid if progress!=1: progress=mod_tools.update_progress(1, 'All passes have been processed', '') ## - Write Selected parameters in a txt file rw_data.write_params(p,p.outdatadir+os.sep+'swot_simulator.output') print("\n Simulated swot files have been written in " + p.outdatadir) print("----------------------------------------------------------")
def create_Nadirlikedata(cycle, ntotfile, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=False): import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Progress bar variables are global global istep global ntot global ifile errnad.wet_tropo1nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.wt=numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice=numpy.zeros(numpy.shape(ngrid.lon))*numpy.nan ## Definition of the time in the model date1=cycle*ngrid.cycle time=ngrid.time+date1 ## Look for satellite data that are beween step-p.timesetp/2 end setp+p.step/2 if p.file_input is True: index_filemodel=numpy.where(((time[-1]-ngrid.timeshift)>=(modeltime-p.timestep/2.)) & ((time[0]-ngrid.timeshift)<(modeltime+p.timestep/2.)) )#[0] ## At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: if progress_bar: progress=mod_tools.update_progress(float(istep)/float(ntotfile*ntot), 'pass: '******'model file: '+list_file[ifile] +', cycle:'+str(cycle+1)) else: progress=None ## If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1]>0: ntot=ntot+numpy.shape(index_filemodel)[1]-1 ind_nadir_time=numpy.where(((time-ngrid.timeshift)>=(modeltime[ifile]-p.timestep/2.)) & ((time-ngrid.timeshift)<(modeltime[ifile]+p.timestep/2.)) ) model_step=eval('rw_data.'+model_data.model+'(file=p.indatadir+os.sep+list_file[ifile], var=p.var)') if p.grid=='regular': model_step.read_var() SSH_model=model_step.vvar[model_data.model_index_lat, :] SSH_model=SSH_model[:,model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model=model_step.vvar ## - Interpolate Model data on a SWOT grid and/or along the nadir track ## if grid is regular, use interpolate.RectBivariateSpline to interpolate if p.grid=='regular' and len(numpy.shape(model_data.vlon))==1: #########################TODO #To be moved to routine rw_data indsorted=numpy.argsort(model_data.vlon) model_data.vlon=model_data.vlon[indsorted] SSH_model=SSH_model[:,indsorted] lonnadir=ngrid.lon[ind_nadir_time[0]].flatten() latnadir=ngrid.lat[ind_nadir_time[0]].flatten() Teval=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(),ngrid.lat[ind_nadir_time[0]].ravel()) SSH_model_mask=+SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)]=0. SSH_true_ind_time=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,SSH_model_mask, kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(),ngrid.lat[ind_nadir_time[0]].ravel()) SSH_true_ind_time[Teval>0]=numpy.nan SSH_true_nadir[ind_nadir_time[0]]=SSH_true_ind_time else: ## Grid is irregular, interpolation can be done using pyresample module if it is installed or griddata function from scipy. ## Note that griddata is slower than pyresample functions. try: import pyresample as pr ngrid.lon=pr.utils.wrap_longitudes(ngrid.lon) ngrid_def=pr.geometry.SwathDefinition(lons=ngrid.lon, lats=ngrid.lat) if p.interpolation=='nearest': SSH_true_nadir[ind_nadir_time[0]]=pr.kd_tree.resample_nearest(swath_def, SSH_model,ngrid_def, radius_of_influence=max(p.delta_al, p.delta_ac)*10**3, epsilon=100) else: SSH_true_nadir[ind_nadir_time[0]]=pr.kd_tree.resample_gauss(swath_def, SSH_model, ngrid_def, radius_of_influence=3*max(p.delta_al, p.delta_ac)*10**3,sigmas=max(p.delta_al, p.delta_ac)*10**3,fill_value=None) except: SSH_true_nadir[ind_nadir_time[0]]=interpolate.griddata((model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) if p.interpolation=='nearest': if modelbox[0]>modelbox[1]: SSH_true_nadir[numpy.where(((ngrid.lon<modelbox[0]) & (ngrid.lon>modelbox[1])) | (ngrid.lat<modelbox[2]) | (ngrid.lat>modelbox[3]))] = numpy.nan else: SSH_true_nadir[numpy.where((ngrid.lon<modelbox[0]) | (ngrid.lon>modelbox[1]) | (ngrid.lat<modelbox[2]) | (ngrid.lat>modelbox[3]))] = numpy.nan vindice[ind_nadir_time[0]]=ifile istep+=1 else: if progress_bar: progress=mod_tools.update_progress(float(istep)/float(ntotfile*ntot), 'pass: '******'model file: '+list_file[ifile] +', cycle:'+str(cycle+1)) else: progress=None istep+=1 errnad.make_error(ngrid, cycle, SSH_true_nadir,p) #, ind[0]) errnad.SSH=errnad.nadir+errnad.wet_tropo1nadir #del SSH_model, model_step, ind_nadir_time return SSH_true_nadir, vindice, time, progress
def create_SWOTlikedata(cycle, ntotfile, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True): import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const '''Create SWOT and nadir errors err and errnad, interpolate model SSH model_data on swath and nadir track, compute SWOT-like and nadir-like data for cycle, SWOT grid sgrid and ngrid. ''' ## - Progress bar variables are global global istep global ntot ## Initialiaze errors and SSH progress=0 err.karin=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.roll=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.phase=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.baseline_dilation=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.timing=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wet_tropo1=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wet_tropo2=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.ssb=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wt=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) SSH_true=numpy.zeros((numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) #, p.nstep)) if p.nadir: err.wet_tropo1nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wet_tropo2nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wtnadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir=numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice_nadir=numpy.zeros(numpy.shape(ngrid.lon))*numpy.nan date1=cycle*sgrid.cycle vindice=numpy.zeros(numpy.shape(SSH_true))*numpy.nan ## Definition of the time in the model time=sgrid.time+date1 ## Look for satellite data that are beween step-p.timesetp/2 end setp+p.step/2 if p.file_input: index_filemodel=numpy.where(((time[-1]-sgrid.timeshift)>=(modeltime-p.timestep/2.)) & ((time[0]-sgrid.timeshift)<(modeltime+p.timestep/2.)) )#[0] ## At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: progress=mod_tools.update_progress(float(istep)/float(ntot*ntotfile), 'pass: '******'model file: '+list_file[ifile] +', cycle:'+str(cycle+1)) ## If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1]>0: ## number of file to be processed used in the progress bar ntot=ntot+numpy.shape(index_filemodel)[1]-1 #if numpy.shape(index)[1]>1: ## Select part of the track that corresponds to the time of the model (+-timestep/2) ind_time=numpy.where(((time-sgrid.timeshift)>=(modeltime[ifile]-p.timestep/2.)) & ((time-sgrid.timeshift)<(modeltime[ifile]+p.timestep/2.)) ) if p.nadir: ind_nadir_time=numpy.where(((time-ngrid.timeshift)>=(modeltime[ifile]-p.timestep/2.)) & ((time-ngrid.timeshift)<(modeltime[ifile]+p.timestep/2.)) ) ## Load data from this model file model_step=eval('rw_data.'+model_data.model+'(file=p.indatadir+os.sep+list_file[ifile], var=p.var)') if p.grid=='regular': model_step.read_var() SSH_model=model_step.vvar[model_data.model_index_lat, :] SSH_model=SSH_model[:,model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model=model_step.vvar ## - Interpolate Model data on a SWOT grid and/or along the nadir track ## if grid is regular, use interpolate.RectBivariateSpline to interpolate if p.grid=='regular' and len(numpy.shape(model_data.vlon))==1: #########################TODO #To be moved to routine rw_data indsorted=numpy.argsort(model_data.vlon) model_data.vlon=model_data.vlon[indsorted] SSH_model=SSH_model[:,indsorted] ## Flatten satellite grid and select part of the track corresponding to the model time lonswot=sgrid.lon[ind_time[0],:].flatten() lonnadir=ngrid.lon[ind_nadir_time[0]].flatten() latswot=sgrid.lat[ind_time[0],:].flatten() latnadir=ngrid.lat[ind_nadir_time[0]].flatten() Teval=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(sgrid.lat[ind_time[0],:].ravel(),sgrid.lon[ind_time[0],:].ravel()) SSH_model_mask=+SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)]=0. SSH_true_ind_time=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,SSH_model_mask, kx=1, ky=1, s=0).ev(sgrid.lat[ind_time[0],:].ravel(),sgrid.lon[ind_time[0],:].ravel()) SSH_true_ind_time[Teval>0]=numpy.nan nal,nac=numpy.shape(sgrid.lon[ind_time[0],:]) SSH_true[ind_time[0], :]=SSH_true_ind_time.reshape(nal,nac) if p.nadir: Teval=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(),ngrid.lat[ind_nadir_time[0]].ravel()) SSH_model_mask=+SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)]=0. SSH_true_ind_time=interpolate.RectBivariateSpline(model_data.vlat,model_data.vlon,SSH_model_mask, kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(),ngrid.lat[ind_nadir_time[0]].ravel()) SSH_true_ind_time[Teval>0]=numpy.nan SSH_true_nadir[ind_nadir_time[0]]=SSH_true_ind_time else: ## Grid is irregular, interpolation can be done using pyresample module if it is installed or griddata function from scipy. ## Note that griddata is slower than pyresample functions. try: import pyresample as pr model_data.vlon=pr.utils.wrap_longitudes(model_data.vlon) sgrid.lon=pr.utils.wrap_longitudes(sgrid.lon) if len(numpy.shape(model_data.vlon))<=1: model_data.vlon, model_data.vlat=numpy.meshgrid(model_data.vlon, model_data.vlat) swath_def=pr.geometry.SwathDefinition(lons=model_data.vlon, lats=model_data.vlat) grid_def=pr.geometry.SwathDefinition(lons=sgrid.lon, lats=sgrid.lat) if p.interpolation=='nearest': SSH_true[ind_time[0], :]=pr.kd_tree.resample_nearest(swath_def, SSH_model,grid_def, radius_of_influence=max(p.delta_al, p.delta_ac)*10**3, epsilon=100) else: SSH_true[ind_time[0], :]=pr.kd_tree.resample_gauss(swath_def, SSH_model, grid_def, radius_of_influence=3*max(p.delta_al, p.delta_ac)*10**3,sigmas=max(p.delta_al, p.delta_ac)*10**3,fill_value=None) if p.nadir: ngrid.lon=pr.utils.wrap_longitudes(ngrid.lon) ngrid_def=pr.geometry.SwathDefinition(lons=ngrid.lon, lats=ngrid.lat) if p.interpolation=='nearest': SSH_true_nadir[ind_nadir_time[0]]=pr.kd_tree.resample_nearest(swath_def, SSH_model,ngrid_def, radius_of_influence=max(p.delta_al, p.delta_ac)*10**3, epsilon=100) else: SSH_true_nadir[ind_nadir_time[0]]=pr.kd_tree.resample_gauss(swath_def, SSH_model, ngrid_def, radius_of_influence=3*max(p.delta_al, p.delta_ac)*10**3,sigmas=max(p.delta_al, p.delta_ac)*10**3,fill_value=None) except: SSH_true[ind_time[0], :]=interpolate.griddata((model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (sgrid.lon[ind_time[0],:], sgrid.lat[ind_time[0],:]), method=p.interpolation) if p.nadir: SSH_true_nadir[ind_nadir_time[0]]=interpolate.griddata((model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) if p.interpolation=='nearest': if modelbox[0]>modelbox[1]: SSH_true[numpy.where(((sgrid.lon<modelbox[0]) & (sgrid.lon>modelbox[1])) | (sgrid.lat<modelbox[2]) | (sgrid.lat>modelbox[3]))] = numpy.nan if p.nadir: SSH_true_nadir[numpy.where(((ngrid.lon<modelbox[0]) & (ngrid.lon>modelbox[1])) | (ngrid.lat<modelbox[2]) | (ngrid.lat>modelbox[3]))] = numpy.nan else: SSH_true[numpy.where((sgrid.lon<modelbox[0]) | (sgrid.lon>modelbox[1]) | (sgrid.lat<modelbox[2]) | (sgrid.lat>modelbox[3]))] = numpy.nan if p.nadir: SSH_true_nadir[numpy.where((ngrid.lon<modelbox[0]) | (ngrid.lon>modelbox[1]) | (ngrid.lat<modelbox[2]) | (ngrid.lat>modelbox[3]))] = numpy.nan vindice[ind_time[0], :]=ifile if p.nadir: vindice_nadir[ind_nadir_time[0]]=ifile del ind_time, SSH_model, model_step, ind_nadir_time istep+=1 else: istep+=1 progress=mod_tools.update_progress(float(istep)/float(ntotfile*ntot), 'pass: '******'no model file provided'+', cycle:'+str(cycle+1)) err.make_error(sgrid, cycle, SSH_true,p) err.make_SSH_error(SSH_true,p) if p.nadir: errnad.make_error(ngrid, cycle, SSH_true_nadir,p) if p.nbeam==1: errnad.SSH=SSH_true_nadir+errnad.nadir+err.wet_tropo1nadir else: errnad.SSH=SSH_true_nadir+errnad.nadir+err.wet_tropo2nadir #if p.file_input: del ind_time, SSH_model, model_step return SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress
def run_nadir(file_param): if os.path.isfile(file_param): # basedir=os.path.dirname(swotsimulator.__file__) shutil.copyfile(file_param, 'params.py') #os.path.join(basedir,'params.py')) else: print("Error: No such file: '%s'" % file_param) sys.exit() try: import params as p except: if os.path.isfile('params.py'): print("There is a wrong entry in your params file" ) import params else: print("Error: No params.py module found") sys.exit() import swotsimulator.build_swath as build_swath import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Initialize some parameters values try: p.shift_lon=p.shift_lon except: p.shift_lon=None try: p.shift_time=p.shift_time except: p.shift_time=None try: model=p.model except: model='NETCDF_MODEL'; p.model= model try: p.model_nan=p.model_nan except: p.model_nan=0. try: p.SSH_factor=p.SSH_factor except: p.SSH_factor=1. #; p.SSH_factor=SSH_factor try: p.nadir=p.nadir except: p.nadir=True try: p.grid=p.grid except: p.grid='regular' p.karin=False ; p.phase=False ; p.roll=False ; p.baseline_dilation=False ; p.timing=False p.halfswath=60. ## - Progress bar variables are global global istep global ntot ## - Read list of user model files """ if p.file_input: list_file = [line.strip() for line in open(p.file_input)] ## - Read model input coordinates ''' # if no modelbox is specified (modelbox=None), the domain of the input data is taken as a modelbox # coordinates from the region defined by modelbox are selected if p.file_input: model_data=eval('rw_data.'+model+'(file=p.indatadir+os.sep+list_file[0])') if p.modelbox: modelbox=numpy.array(p.modelbox, dtype='float') ## Use convert to 360 data modelbox[0]=(modelbox[0]+360)%360 if modelbox[1] != 360: modelbox[1]=(modelbox[1]+360)%360 else: if p.file_input: modelbox=model_data.calc_box() else: print('modelbox should be provided if no model file is provided') sys.exit() if p.file_input: model_data.read_coordinates() ## Select model data in the region modelbox if p.grid=='regular': model_data.model_index_lon=numpy.where(((modelbox[0]-1)<=model_data.vlon) & (model_data.vlon<=(modelbox[1]+1)))[0] model_data.model_index_lat=numpy.where(((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))[0] model_data.vlon=model_data.vlon[model_data.model_index_lon] model_data.vlat=model_data.vlat[model_data.model_index_lat] else: model_data.model_index=numpy.where(((modelbox[0]-1)<=model_data.vlon) & (model_data.vlon<=(modelbox[1]+1)) & ((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))#[0] model_data.model=model model_data.vloncirc=numpy.rad2deg(numpy.unwrap(model_data.vlon)) ## Ugly trick when model box is [0 360] to avoid box being empty (360=0%360) if modelbox[1]==0: modelbox[1]=359.99 ## - Initialize random coefficients that are used to compute ## random errors following the specified spectrum err, errnad=load_error(p) ## - Compute interpolated SSH and errors for each pass, at each ## cycle print('Compute interpolated SSH and errors:') ## Model time step modeltime=numpy.arange(0,p.nstep*p.timestep, p.timestep) ## Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) ## Initialize progress bar variables istep=0; ntot=1 ## Initialize list of satellites istring=len(p.dir_setup) if not isinstance(p.filesat, list): p.filesat=[p.filesat] for filesat in p.filesat: ## Select satellite ntmp, nfilesat=os.path.split(filesat[istring:-4]) ## Make satellite orbit grid if p.makesgrid: print('\n Force creation of satellite grid') ngrid=build_swath.makeorbit(modelbox, p, orbitfile=filesat) ngrid.file=p.outdatadir+os.sep+nfilesat+'_grid.nc' ngrid.write_orb() ngrid.ipass=nfilesat ngrid.gridfile=p.outdatadir+os.sep+nfilesat+'_grid.nc' else: ## To be replaced by load_ngrid ngrid = rw_data.Sat_nadir(file=p.filesgrid+'.nc') ngrid.ipass=nfilesat ngrid.gridfile=p.outdatadir+os.sep+nfilesat+'_grid.nc' cycle=0 ; x_al=[] ; al_cycle=0 ; timeshift=0 ngrid.load_orb(cycle=cycle,x_al=x_al, al_cycle=al_cycle, timeshift=timeshift) ngrid.loncirc=numpy.rad2deg(numpy.unwrap(ngrid.lon)) #ngrid=load_ngrid(sgridfile, p) ## Select model data around the swath to reduce interpolation cost in griddata ## - Generate SWOT like and nadir-like data: ## Compute number of cycles needed to cover all nstep model timesteps if p.file_input: model_index=numpy.where(((numpy.min(ngrid.lon))<=model_data.vlon) & (model_data.vlon<=(numpy.max(ngrid.lon))) & ((numpy.min(ngrid.lat))<=model_data.vlat) & (model_data.vlat<=(numpy.max(ngrid.lat)))) rcycle=(p.timestep*p.nstep)/float(ngrid.cycle) ncycle=int(rcycle) ## Loop on all cycles for cycle in range(0,ncycle+1): if ifile>(p.nstep/p.timestep +1): break ## Create SWOT-like and Nadir-like data if not p.file_input : model_data=[] SSH_true_nadir, vindice, time, progress=create_Nadirlikedata(cycle, numpy.shape(p.filesat)[0]*rcycle, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=True) #SSH_true_nadir, vindice_nadir=create_Nadirlikedata(cycle, sgrid, ngrid, model_data, modeltime, err, errnad, p) ## Save outputs in a netcdf file ngrid.gridfile=filesat if (~numpy.isnan(vindice)).any() or not p.file_input: err=errnad ; err.wtnadir=numpy.zeros((1)) ; err.wet_tropo2nadir=numpy.zeros((1)) save_Nadir(cycle, ngrid, errnad, err , p,time=time, vindice_nadir=vindice, SSH_true_nadir=SSH_true_nadir) del time #if p.file_input: del index ngrid.lon=(ngrid.lon+360)%360 if p.file_input: model_data.vlon=(model_data.vlon+360)%360 modelbox[0]=(modelbox[0]+360)%360 modelbox[1]=(modelbox[1]+360)%360 del ngrid if progress!=1: progress=mod_tools.update_progress(1, 'All passes have been processed', '') ## - Write Selected parameters in a txt file rw_data.write_params(p,p.outdatadir+os.sep+'nadir_simulator.output') print("\n Simulated orbit files have been written in " + p.outdatadir) print("----------------------------------------------------------")
def makeorbit(modelbox,p,orbitfile='orbit_292.txt', filealtimeter=None): '''Computes the swath of SWOT satellites on a subdomain. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Swath parameters (half gap distance p.halfgap, half swath distance p.halfswath, along track resolution p.delta_al, across track resolution p.delta_ac). \n Outputs are netcdf files containing SWOT grid (along track distance x_al, across track distance from nadir x_ac, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' npoints=1 ## --Load SWOT orbit ground track print('Load data from orbit file') volon, volat, votime=numpy.loadtxt(orbitfile, usecols=(0,1,2), unpack=True) ## --If orbit is at low resolution, interpolate at 0.5 s resolution if numpy.mean(votime[1:]-votime[:-1])>0.5: x,y,z=mod_tools.spher2cart(volon, volat) time_hr=numpy.arange(0.,votime[-1],0.5) f = interpolate.interp1d(votime, x) x_hr=f(time_hr) f = interpolate.interp1d(votime, y) y_hr=f(time_hr) f = interpolate.interp1d(votime, z) z_hr=f(time_hr) lon_hr=numpy.zeros(len(x_hr))+numpy.nan lat_hr=numpy.zeros(len(x_hr))+numpy.nan for ii in range(len(x_hr)): lon_hr[ii],lat_hr[ii]=mod_tools.cart2spher(x_hr[ii],y_hr[ii],z_hr[ii]) time_hr=time_hr/86400. ind=numpy.where((time_hr<20.86455)) volon=lon_hr[ind] volat=lat_hr[ind] votime=time_hr[ind] ## --Get number of points in orbit nop=numpy.shape(votime)[0] ## --Get cycle period. tcycle=votime[nop-1]+votime[1]-votime[0] # shift time if the user needs to shift the time of the orbit try: pshift_time=p.shift_time if pshift_time: shift_index=numpy.where(votime>=pshift_time)[0] volon=numpy.hstack([volon[shift_index[0][0]:], volon[:shift_index[0][0]]]) volat=numpy.hstack([volat[shift_index[0][0]:], volat[:shift_index[0][0]]]) except: p.shift_time=None # shift lon if the user needs to shift the localisation of the orbit try: pshift_lon=p.shift_lon if pshift_lon: volon=volon+pshift_lon except: p.shift_lon=None volon=(volon+360)%360 ## --Rearrange orbit starting from pass 1 # Detect the beginning of pass 1 in orbit txt file. By definition, it is the first passage at southernmost latitude. dlat=numpy.roll(volat,1) -volat ind=numpy.where((dlat<0) & (numpy.roll(dlat,1)>=0)) # Shift coordinates, so that the first point of the orbit is the beginning of pass 1 decal=ind[0][-1] timeshift=votime[-1]-votime[decal] volon=numpy.hstack([volon[decal:], volon[:decal]]) #numpy.roll(volon,decal) volat=numpy.hstack([volat[decal:], volat[:decal]]) #numpy.roll(volat,decal) votime=numpy.hstack([votime[decal:], votime[:decal]]) #numpy.roll(votime,decal) votime=(votime-votime[0])%tcycle if votime[numpy.where(votime<0)]: print('WARNING: there are negative times in your orbit') del ind # Compute the initial time of each pass dlat=numpy.roll(volat,1) -volat ind=numpy.where(((dlat<0) & (numpy.roll(dlat,1)>=0))|((dlat>0) & (numpy.roll(dlat,1)<=0))) #index=numpy.hstack([0,ind[0]-1]) index=ind[0] passtime=votime[index] # Times of pass ## -- Compute accumulated along-track distance, longitude, latitude in the subdomain # chosen by the user or given by the model # Extract points in the domain and count the number of points (nop) in the subdomain #modelbox=[lonmin lonmax latmin latmax] add margin around the domain plus one point to compute Satdir matnpbox=numpy.zeros((nop)) if modelbox[0]>modelbox[1]: matnpbox[numpy.where((((modelbox[0]-p.halfswath/(const.deg2km*math.cos(modelbox[2]*math.pi/180.)))<=volon) | (volon<=(modelbox[1]+p.halfswath/(const.deg2km*math.cos(modelbox[3]*math.pi/180.))))) & ((modelbox[2]-p.halfswath/const.deg2km)<=volat) & ((modelbox[3]+p.halfswath/const.deg2km)>=volat))]=1 else: matnpbox[numpy.where(((modelbox[0]-p.halfswath/(const.deg2km*math.cos(modelbox[2]*math.pi/180.)))<=volon) & (volon<=(modelbox[1]+p.halfswath/(const.deg2km*math.cos(modelbox[3]*math.pi/180.)))) & ((modelbox[2]-p.halfswath/const.deg2km)<=volat) & ((modelbox[3]+p.halfswath/const.deg2km)>=volat))]=1 norp=int(numpy.sum(matnpbox)) # Initialize total distance travelled by the satellite since the first point of the cycle # in the subdomain at low (orbital file) resolution x_al_lr=numpy.zeros((norp)) lon_lr=numpy.zeros((norp)) lat_lr=numpy.zeros((norp)) stime_lr=numpy.zeros((norp)) # Initialize vector with accumulated distance travelled by the satellite indp = 0 distance=numpy.zeros((nop)) # Compute and store distances and coordinates that are in the defined subdomain print('Compute SWOT nadir coordinate in the new domain') for i in range(0,nop-1): mod_tools.update_progress(float(i)/float(nop-1), None, None) if abs(volon[i+1]-volon[i])>1: if volon[i+1]>180. : volon[i+1]=volon[i+1]-360 if volon[i]>180. : volon[i]=volon[i]-360 distance[i+1]=distance[i]+numpy.sqrt(((volon[i+1]-volon[i])*const.deg2km*numpy.cos(volat[i+1]*2*math.pi/360.))**2 + ((volat[i+1]-volat[i])*const.deg2km)**2 ) #numpy.sum(dl[:i]) volon[i+1]=(volon[i+1]+360)%360 if matnpbox[i]: x_al_lr[indp] = distance[i] lon_lr[indp] = (volon[i]+360)%360 lat_lr[indp] = volat[i] stime_lr[indp] = votime[i] indp=indp+1 ## -- Interpolate orbit at delta_al km resolution (default is delta_al=1) #Detect gap in time in stime (to detect step in x_al, lon and lat) dstime=stime_lr[:]-numpy.roll(stime_lr[:],1) ind=numpy.where(dstime>3*(votime[1]-votime[0])) index=numpy.hstack([0,ind[0]]) nindex=numpy.shape(index)[0] # Initialize along track distance, time and coordinates at delta_al resolution if nindex>1: dgap=numpy.zeros((nindex)) for i in range(1,nindex): dgap[i]=x_al_lr[index[i]]-x_al_lr[max(index[i]-1,0)] Ninterp=int((x_al_lr[-1]-x_al_lr[0] -sum(dgap))/float(p.delta_al))+1 x_al=numpy.zeros((Ninterp)) stime=numpy.zeros((Ninterp)) lon=numpy.zeros((Ninterp)) lat=numpy.zeros((Ninterp)) imin=0 ; imax=0 for i in range(0,nindex-1): imax=imin+int((x_al_lr[index[i+1]-1]-x_al_lr[index[i]])/float(p.delta_al))+1 if imax<=(imin+1): x_al[imin]=x_al_lr[index[i]] stime[imin]=stime_lr[index[i]] lon[imin]=lon_lr[index[i]] lat[imin]=lat_lr[index[i]] else: x_al[imin:imax]=numpy.arange(x_al_lr[index[i]],x_al_lr[index[i+1]-1], p.delta_al) stime[imin:imax]=numpy.interp(x_al[imin:imax], x_al_lr[index[i]:index[i+1]], stime_lr[index[i]:index[i+1]]) loncirc=numpy.rad2deg(numpy.unwrap(numpy.deg2rad(lon_lr[index[i]:index[i+1]]))) #if numpy.min(lon_lr[index[i]:index[i+1]])<1. and numpy.max(lon_lr[index[i]:index[i+1]])>359.: # lontmp=lon_lr[index[i]:index[i+1]] # lontmp[numpy.where(lontmp>180.)]=lontmp[numpy.where(lontmp>180.)]-360. # lon[imin:imax]=numpy.interp(x_al[imin:imax], x_al_lr[index[i]:index[i+1]], lontmp) #_lr[index[i]:index[i+1]]) # lon[imin:imax]=(lon[imin:imax]+360)%360 #else: # lon[imin:imax]=numpy.interp(x_al[imin:imax], x_al_lr[index[i]:index[i+1]], lon_lr[index[i]:index[i+1]]) lon[imin:imax]=numpy.interp(x_al[imin:imax], x_al_lr[index[i]:index[i+1]], loncirc) lat[imin:imax]=numpy.interp(x_al[imin:imax], x_al_lr[index[i]:index[i+1]], lat_lr[index[i]:index[i+1]]) imin=imax x_al[imin:]=numpy.arange(x_al_lr[index[-1]],x_al_lr[index[-1]]+(Ninterp-imin)*p.delta_al, p.delta_al) stime[imin:]=numpy.interp(x_al[imin:], x_al_lr[index[-1]:], stime_lr[index[-1]:]) loncirc=numpy.rad2deg(numpy.unwrap(numpy.deg2rad(lon_lr[index[-1]:]))) #if numpy.min(lon_lr[index[-1]:])<1. and numpy.max(lon_lr[index[-1]:])>539: # lontmp=lon_lr[index[-1]:] # lontmp[numpy.where(lontmp>180.)]=lontmp[numpy.where(lontmp>180.)]-360. # lon[imin:]=numpy.interp(x_al[imin:], x_al_lr[index[-1]:], lontmp) # lon[imin:]=(lon[imin:]+360)%360 #else: # lon[imin:]=numpy.interp(x_al[imin:], x_al_lr[index[-1]:], lon_lr[index[-1]:]) lon[imin:]=numpy.interp(x_al[imin:], x_al_lr[index[-1]:], loncirc) lat[imin:]=numpy.interp(x_al[imin:], x_al_lr[index[-1]:], lat_lr[index[-1]:]) else: Ninterp=int((x_al_lr[-2]-x_al_lr[0] )/float(p.delta_al))+1 x_al=numpy.zeros((Ninterp)) stime=numpy.zeros((Ninterp)) lon=numpy.zeros((Ninterp)) lat=numpy.zeros((Ninterp)) x_al=numpy.arange(x_al_lr[0],x_al_lr[-2], p.delta_al) stime=numpy.interp(x_al, x_al_lr[:-1], stime_lr[:-1]) loncirc=numpy.rad2deg(numpy.unwrap(numpy.deg2rad(lon_lr[:-1]))) lon=numpy.interp(x_al, x_al_lr[:-1],loncirc) lat=numpy.interp(x_al, x_al_lr[:-1],lat_lr[:-1]) lon=lon%360 orb=rw_data.Sat_nadir(file=orbitfile[:-4]+'.nc') orb.x_al=x_al orb.time=stime orb.lon=lon orb.lat=lat orb.cycle=tcycle orb.al_cycle=distance[-1] orb.passtime=numpy.sort(passtime) orb.timeshift=timeshift return orb
def run_simulator(p, die_on_error=False, nadir_alone=False): '''Main routine to run simulator, input is the imported parameter file, no outputs are returned but netcdf grid and data files are written as well as a skimulator.output file to store all used parameter. ''' # - Initialize some parameters values timestart = datetime.datetime.now() mod_tools.initialize_parameters(p) mod_tools.check_path(p) # - Read list of user model files """ model_data, list_file = mod.load_coordinate_model(p) ## - Read model input coordinates ''' ## if no modelbox is specified (modelbox=None), the domain of the input ## data is taken as a modelbox ## coordinates from the region defined by modelbox are selected if p.modelbox is not None: modelbox = numpy.array(p.modelbox, dtype='float') # Use convert to 360 data modelbox[0] = (modelbox[0] + 360) % 360 if modelbox[1] != 360: modelbox[1] = (modelbox[1] + 360) % 360 else: if p.file_input is not None: modelbox = model_data.calc_box() else: logger.error('modelbox should be provided if no model file is' 'provided') sys.exit(1) p.modelbox_calc = modelbox if p.file_input is not None: model_data.read_coordinates() # Select model data in the region modelbox model_data.len_coord = len(numpy.shape(model_data.vlon)) if p.grid == 'regular' or model_data.len_coord == 1: if modelbox[0] < modelbox[1]: _i_lon = numpy.where(((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)))[0] else: _i_lon = numpy.where(((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)))[0] model_data.model_index_lon = _i_lon _i_lat = numpy.where(((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1)))[0] model_data.model_index_lat = _i_lat model_data.vlon = model_data.vlon[model_data.model_index_lon] model_data.vlat = model_data.vlat[model_data.model_index_lat] else: if modelbox[0] < modelbox[1]: _i_box = numpy.where(((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) else: _i_box = numpy.where(((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) model_data.model_index = _i_box model_data.vlon = model_data.vlon[model_data.model_index] model_data.vlat = model_data.vlat[model_data.model_index] model_data.model = p.model model_data.vloncirc = numpy.rad2deg(numpy.unwrap(model_data.vlon)) if modelbox[1] == 0: modelbox[1] = 359.99 # - Make SWOT grid if necessary """ if p.makesgrid is True: logger.info('\n Force creation of SWOT grid') # make nadir orbit orb = build_swath.makeorbit(modelbox, p, orbitfile=p.filesat) # build swath for this orbit if nadir_alone is True: build_swath.orbit2nadir(modelbox, p, orb, die_on_error) logger.info("\n Nadir tracks have been written in " "{}".format(p.outdatadir)) else: build_swath.orbit2swath(modelbox, p, orb, die_on_error) logger.info("\n SWOT Grids and nadir tracks have been written in " "{}".format(p.outdatadir)) logger.info("-----------------------------------------------") # - Initialize random coefficients that are used to compute # random errors following the specified spectrum err, errnad = mod.load_error(p, nadir_alone=nadir_alone) # - Compute interpolated SSH and errors for each pass, at each # cycle logger.info('Compute interpolated SSH and errors:') # load all SWOT grid files (one for each pass) listsgridfile = sorted(glob.glob(p.filesgrid + '_p*.nc')) if not listsgridfile: logger.error('\n There is no SWOT grid file in {}, run simulator with' ' option makesgrid set to true in your params' ' file'.format(p.outdatadir)) sys.exit(1) # Build model time steps from parameter file modeltime = numpy.arange(0, p.nstep * p.timestep, p.timestep) # Remove the grid from the list of model files if p.file_input and p.file_grid_model is None: logger.info("WARNING: the first file is not used to build data") list_file.remove(list_file[0]) if len(modeltime) > len(list_file): logger.error('There is not enough model files in the list of' 'files') sys.exit(1) # - Loop on SWOT grid files to construct a list of jobs jobs = [] p2 = mod_tools.todict(p) for sgridfile in listsgridfile: jobs.append([ sgridfile, p2, listsgridfile, list_file, modelbox, model_data, modeltime, err, errnad ]) ok = False # - Process list of jobs using multiprocessing try: ok = make_swot_data(p.proc_count, jobs, die_on_error, p.progress_bar) except DyingOnError: logger.error('An error occurred and all errors are fatal') sys.exit(1) # - Write Selected parameters in a txt file timestop = datetime.datetime.now() timestop = timestop.strftime('%Y%m%dT%H%M%SZ') timestart = timestart.strftime('%Y%m%dT%H%M%SZ') op_file = 'swot_simulator_{}_{}.output'.format(timestart, timestop) op_file = os.path.join(p.outdatadir, op_file) rw_data.write_params(p, op_file) if ok is True: if p.progress_bar is True: __ = mod_tools.update_progress(1, 'All passes have been processed', '') else: __ = logger.info('All passes have been processed') logger.info("\n Simulated swot files have been written in {}".format( p.outdatadir)) logger.info(''.join(['-'] * 61)) #"----------------------------------------------------------") sys.exit(0) logger.error('\nERROR: At least one of the outputs was not saved.') sys.exit(1)
def orbit2swath(modelbox, p, orb): '''Computes the swath of SWOT satellites on a subdomain from an orbit. The path of the satellite is given by the orbit file and the subdomain corresponds to the one in the model. Note that a subdomain can be manually added in the parameters file. \n Inputs are satellite orbit (p.filesat), subdomain (modelbox), Swath parameters (half gap distance p.halfgap, half swath distance p.halfswath, along track resolution p.delta_al, across track resolution p.delta_ac). \n Outputs are netcdf files containing SWOT grid (along track distance x_al, across track distance from nadir x_ac, longitude lon and latitude lat, number of days in a cycle cycle, distance crossed in a cycle cycle_al, time''' ''' Compute orbit from Swath ''' # - Load altimeter orbit npoints = 1 x_al = orb.x_al stime = orb.time lon = orb.lon lat = orb.lat tcycle = orb.cycle al_cycle = orb.al_cycle passtime = orb.passtime # - Compute accross track distances from nadir # Number of points in half of the swath nhalfswath = int((p.halfswath-p.halfgap)/p.delta_ac) + 1 # Across track distance from nadir x_ac = numpy.zeros((2*nhalfswath)) for i in range(0, int(nhalfswath)): x_ac[i] = -(nhalfswath - i)*p.delta_ac - p.halfgap + p.delta_ac x_ac[i + nhalfswath] = i * p.delta_ac + p.halfgap # - Computation of SWOT grid and storage by passes logger.info('\n Compute SWOT grid') # Detect first pass that is in the subdomain ipass0 = 0 # strpass = [] # Loop on all passes after the first pass detected for ipass in range(ipass0, numpy.shape(passtime)[0]): # Detect indices corresponding to the pass if ipass == numpy.shape(passtime)[0]-1: ind = numpy.where((stime >= passtime[ipass]))[0] else: ind = numpy.where((stime >= passtime[ipass]) & (stime < passtime[ipass+1]))[0] nind = numpy.shape(ind)[0] # Compute swath grid if pass is in the subdomain if nind > 5: pstep = float(ipass + 1) / float(numpy.shape(passtime)[0]) str1 = 'selected pass: {}'.format(ipass + 1) mod_tools.update_progress(pstep, str1, None) # Initialize SWOT grid, grid variables and Satellite # direction and Location filesgrid = '{}_p{:03d}.nc'.format(p.filesgrid,ipass + 1) sgrid = rw_data.Sat_SWOT(nfile=filesgrid) sgrid.x_al = x_al[ind] sgrid.x_ac = x_ac sgrid.cycle = tcycle sgrid.al_cycle = al_cycle sgrid.time = stime[ind] sgrid.lon = numpy.zeros((nind, 2*nhalfswath)) sgrid.lat = numpy.zeros((nind, 2*nhalfswath)) SatDir = numpy.zeros((int(nind/npoints), 3)) SatLoc = numpy.zeros((int((nind)/npoints), 3)) # Initialize Nadir track, grid variables filengrid = '{}nadir_p{:03d}.nc'.format(p.filesgrid,ipass + 1) ngrid = rw_data.Sat_nadir(nfile=filengrid) ngrid.x_al = x_al[ind] ngrid.cycle = tcycle ngrid.al_cycle = al_cycle ngrid.time = stime[ind] # Project in cartesian coordinates satellite ground location s2cart = mod_tools.spher2cart(lon[ind[0]: ind[-1]+1: npoints], lat[ind[0]: ind[-1]+1: npoints]) SatLoc[:, 0], SatLoc[:, 1], SatLoc[:, 2] = s2cart # Compute satellite direction (SatLoc is periodic) SatDir[1: -1, 0] = ((SatLoc[2:, 0] - SatLoc[: -2, 0]) / numpy.sqrt(SatLoc[1: -1, 0]**2 + SatLoc[1: -1, 1]**2 + SatLoc[1: -1, 2]**2)) SatDir[1: -1, 1] = ((SatLoc[2:, 1] - SatLoc[: -2, 1]) / numpy.sqrt(SatLoc[1: -1, 0]**2 + SatLoc[1: -1, 1]**2 + SatLoc[1: -1, 2]**2)) SatDir[1: -1, 2] = ((SatLoc[2:, 2] - SatLoc[: -2, 2]) / numpy.sqrt(SatLoc[1: -1, 0]**2 + SatLoc[1: -1, 1]**2 + SatLoc[1: -1, 2]**2)) SatDir[-1, :] = SatDir[-2, :] SatDir[0, :] = SatDir[1, :] # Rotate from earth center around satellite direction to compute # swath points of angles between the borders of the swath in left # and right swath for i in range(0, nind, npoints): for j in range(0, int(nhalfswath)): R = mod_tools.rotationmat3D(float((j*p.delta_ac+p.halfgap) / (const.Rearth*10**-3)), SatDir[int(i/npoints), :]) ObsLoc = numpy.dot(R, SatLoc[int(i/npoints)]) cs = mod_tools.cart2spher(ObsLoc[0], ObsLoc[1], ObsLoc[2]) sgrid.lon[i, nhalfswath+j], sgrid.lat[i, nhalfswath+j] = cs ObsLoc = numpy.dot(numpy.transpose(R), SatLoc[int(i/npoints)]) cs = mod_tools.cart2spher(ObsLoc[0], ObsLoc[1], ObsLoc[2]) sgrid.lon[i, nhalfswath-j-1], sgrid.lat[i, nhalfswath-j-1] = cs if npoints > p.delta_al: if i >= npoints: sgrid.lon[i-npoints: i, nhalfswath+j] = numpy.arange(sgrid.lon[i-npoints, nhalfswath+j], sgrid.lon[i, nhalfswath+j], (sgrid.lon[i, nhalfswath+j]-sgrid.lon[i-npoints, nhalfswath+j])/npoints) sgrid.lat[i-npoints: i, nhalfswath+j] = numpy.arange(sgrid.lat[i-npoints, nhalfswath+j], sgrid.lat[i, nhalfswath+j], (sgrid.lat[i, nhalfswath+j]-sgrid.lat[i-npoints, nhalfswath+j])/npoints) # if npoints>p.delta_al: # print 'interp not coded' # for j in range(0, 2*int(nhalfswath+1)): # sgrid.lon[:,j]=numpy.arange(sgrid.lon[0,j], sgrid.lon[ind[-1],j], # (sgrid.lon[-1,j]-sgrid.lon[0,j])/npoints) # sgrid.lat[:,j]=numpy.arange(sgrid.lat[0,j], sgrid.lat[-1,j], # (sgrid.lat[-1,j]-sgrid.lat[0,j])/npoints) # Save Sgrid object sgrid.timeshift = orb.timeshift ngrid.timeshift = orb.timeshift ngrid.lon = (lon[ind] + 360) % 360 ngrid.lat = lat[ind] sgrid.lon_nadir = (lon[ind] + 360) % 360 sgrid.lat_nadir = lat[ind] # Remove grid file if it exists and save it if os.path.exists(filesgrid): os.remove(filesgrid) sgrid.write_swath() if p.nadir: if os.path.exists(filengrid): os.remove(filengrid) ngrid.write_orb() mod_tools.update_progress(1, 'All swaths have been processed', ' ') return None
def run_simulator(file_param): import swotsimulator.build_swath as build_swath import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Initialize some parameters values try: p.shift_lon = p.shift_lon except: p.shift_lon = None try: p.shift_time = p.shift_time except: p.shift_time = None try: model = p.model except: model = 'NETCDF_MODEL' p.model = model try: p.model_nan = p.model_nan except: p.model_nan = 0. try: p.SSH_factor = p.SSH_factor except: p.SSH_factor = 1. #; p.SSH_factor=SSH_factor try: p.nadir = p.nadir except: p.nadir = True try: p.grid = p.grid except: p.grid = 'regular' ## - Progress bar variables are global global istep global ntot ## - Read list of user model files """ if p.file_input: list_file = [line.strip() for line in open(p.file_input)] ## - Read model input coordinates ''' # if no modelbox is specified (modelbox=None), the domain of the input data is taken as a modelbox # coordinates from the region defined by modelbox are selected if p.file_input: model_data = eval('rw_data.' + model + '(file=p.indatadir+os.sep+list_file[0])') if p.modelbox: modelbox = numpy.array(p.modelbox, dtype='float') ## Use convert to 360 data modelbox[0] = (modelbox[0] + 360) % 360 if modelbox[1] != 360: modelbox[1] = (modelbox[1] + 360) % 360 else: if p.file_input: modelbox = model_data.calc_box() else: print('modelbox should be provided if no model file is provided') sys.exit() if p.file_input: model_data.read_coordinates() ## Select model data in the region modelbox if p.grid == 'regular': if modelbox[0] < modelbox[1]: model_data.model_index_lon = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)))[0] else: model_data.model_index_lon = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)))[0] model_data.model_index_lat = numpy.where( ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1)))[0] model_data.vlon = model_data.vlon[model_data.model_index_lon] model_data.vlat = model_data.vlat[model_data.model_index_lat] else: if modelbox[0] < modelbox[1]: model_data.model_index = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) #[0] else: model_data.model_index = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) | (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) #[0] model_data.model = model model_data.vloncirc = numpy.rad2deg(numpy.unwrap(model_data.vlon)) if modelbox[1] == 0: modelbox[1] = 359.99 ## - Make SWOT grid if necessary """ if p.makesgrid: print('\n Force creation of SWOT grid') orb = build_swath.makeorbit(modelbox, p, orbitfile=p.filesat) build_swath.orbit2swath(modelbox, p, orb) print("\n SWOT Grids and nadir tracks have been written in " + p.outdatadir) print("-----------------------------------------------") ## - Initialize random coefficients that are used to compute ## random errors following the specified spectrum err, errnad = load_error(p) ## - Compute interpolated SSH and errors for each pass, at each ## cycle print('Compute interpolated SSH and errors:') ## load all SWOT grid files (one for each pass) listsgridfile = sorted(glob.glob(p.filesgrid + '_p*.nc')) if not listsgridfile: print( '\n There is no SWOT grid file in ' + p.outdatadir + ', run simulator with option makesgrid set to true in your params file' ) sys.exit() ## Model time step modeltime = numpy.arange(0, p.nstep * p.timestep, p.timestep) ## Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) ## Initialize progress bar variables istep = 0 ntot = 1 ## - Loop on SWOT grid files for sgridfile in listsgridfile: ## Load SWOT grid files (Swath and nadir) sgrid = load_sgrid(sgridfile, p) sgrid.gridfile = sgridfile if p.nadir: ngrid = load_ngrid(sgridfile, p) ngrid.gridfile = sgridfile ## Select model data around the swath to reduce interpolation cost in griddata ## - Generate SWOT like and nadir-like data: ## Compute number of cycles needed to cover all nstep model timesteps rcycle = (p.timestep * p.nstep) / float(sgrid.cycle) ncycle = int(rcycle) ## Loop on all cycles for cycle in range(0, ncycle + 1): if ifile > (p.nstep / p.timestep + 1): break ## Create SWOT-like and Nadir-like data if not p.file_input: model_data = [] SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress = create_SWOTlikedata( cycle, numpy.shape(listsgridfile)[0] * rcycle, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True) #SSH_true_nadir, vindice_nadir=create_Nadirlikedata(cycle, sgrid, ngrid, model_data, modeltime, err, errnad, p) ## Save outputs in a netcdf file if (~numpy.isnan(vindice)).any() or not p.file_input: save_SWOT(cycle, sgrid, err, p, time=time, vindice=vindice, SSH_true=SSH_true) if p.nadir: save_Nadir(cycle, ngrid, errnad, err, p, time=time, vindice_nadir=vindice_nadir, SSH_true_nadir=SSH_true_nadir) del time #if p.file_input: del index sgrid.lon = (sgrid.lon + 360) % 360 ngrid.lon = (ngrid.lon + 360) % 360 if p.file_input: model_data.vlon = (model_data.vlon + 360) % 360 modelbox[0] = (modelbox[0] + 360) % 360 modelbox[1] = (modelbox[1] + 360) % 360 del sgrid, ngrid if progress != 1: progress = mod_tools.update_progress(1, 'All passes have been processed', '') ## - Write Selected parameters in a txt file rw_data.write_params(p, p.outdatadir + os.sep + 'swot_simulator.output') print("\n Simulated swot files have been written in " + p.outdatadir) print("----------------------------------------------------------")
def create_SWOTlikedata(cycle, ntotfile, list_file, modelbox, sgrid, ngrid, model_data, modeltime, err, errnad, p, progress_bar=True): import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const '''Create SWOT and nadir errors err and errnad, interpolate model SSH model_data on swath and nadir track, compute SWOT-like and nadir-like data for cycle, SWOT grid sgrid and ngrid. ''' ## - Progress bar variables are global global istep global ntot ## Initialiaze errors and SSH progress = 0 err.karin = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.roll = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.phase = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.baseline_dilation = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.timing = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wet_tropo1 = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wet_tropo2 = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.ssb = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) err.wt = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) SSH_true = numpy.zeros( (numpy.shape(sgrid.lon)[0], numpy.shape(sgrid.lon)[1])) #, p.nstep)) if p.nadir: err.wet_tropo1nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wet_tropo2nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) err.wtnadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice_nadir = numpy.zeros(numpy.shape(ngrid.lon)) * numpy.nan date1 = cycle * sgrid.cycle vindice = numpy.zeros(numpy.shape(SSH_true)) * numpy.nan ## Definition of the time in the model time = sgrid.time + date1 ## Look for satellite data that are beween step-p.timesetp/2 end setp+p.step/2 if p.file_input: index_filemodel = numpy.where(((time[-1] - sgrid.timeshift) >= (modeltime - p.timestep / 2.)) & ((time[0] - sgrid.timeshift) < (modeltime + p.timestep / 2.))) #[0] ## At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: progress = mod_tools.update_progress( float(istep) / float(ntot * ntotfile), 'pass: '******'model file: ' + list_file[ifile] + ', cycle:' + str(cycle + 1)) ## If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1] > 0: ## number of file to be processed used in the progress bar ntot = ntot + numpy.shape(index_filemodel)[1] - 1 #if numpy.shape(index)[1]>1: ## Select part of the track that corresponds to the time of the model (+-timestep/2) ind_time = numpy.where(((time - sgrid.timeshift) >= ( modeltime[ifile] - p.timestep / 2.)) & ( (time - sgrid.timeshift) < (modeltime[ifile] + p.timestep / 2.))) if p.nadir: ind_nadir_time = numpy.where(((time - ngrid.timeshift) >= ( modeltime[ifile] - p.timestep / 2.)) & ( (time - ngrid.timeshift) < (modeltime[ifile] + p.timestep / 2.))) ## Load data from this model file model_step = eval( 'rw_data.' + model_data.model + '(file=p.indatadir+os.sep+list_file[ifile], var=p.var)') if p.grid == 'regular': model_step.read_var() SSH_model = model_step.vvar[model_data.model_index_lat, :] SSH_model = SSH_model[:, model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model = model_step.vvar ## - Interpolate Model data on a SWOT grid and/or along the nadir track ## if grid is regular, use interpolate.RectBivariateSpline to interpolate if p.grid == 'regular' and len(numpy.shape( model_data.vlon)) == 1: #########################TODO #To be moved to routine rw_data indsorted = numpy.argsort(model_data.vlon) model_data.vlon = model_data.vlon[indsorted] SSH_model = SSH_model[:, indsorted] ## Flatten satellite grid and select part of the track corresponding to the model time lonswot = sgrid.lon[ind_time[0], :].flatten() lonnadir = ngrid.lon[ind_nadir_time[0]].flatten() latswot = sgrid.lat[ind_time[0], :].flatten() latnadir = ngrid.lat[ind_nadir_time[0]].flatten() Teval = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(sgrid.lat[ind_time[0], :].ravel(), sgrid.lon[ind_time[0], :].ravel()) SSH_model_mask = +SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)] = 0. SSH_true_ind_time = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, SSH_model_mask, kx=1, ky=1, s=0).ev(sgrid.lat[ind_time[0], :].ravel(), sgrid.lon[ind_time[0], :].ravel()) SSH_true_ind_time[Teval > 0] = numpy.nan nal, nac = numpy.shape(sgrid.lon[ind_time[0], :]) SSH_true[ind_time[0], :] = SSH_true_ind_time.reshape( nal, nac) if p.nadir: Teval = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel()) SSH_model_mask = +SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)] = 0. SSH_true_ind_time = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, SSH_model_mask, kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel()) SSH_true_ind_time[Teval > 0] = numpy.nan SSH_true_nadir[ind_nadir_time[0]] = SSH_true_ind_time else: ## Grid is irregular, interpolation can be done using pyresample module if it is installed or griddata function from scipy. ## Note that griddata is slower than pyresample functions. try: import pyresample as pr model_data.vlon = pr.utils.wrap_longitudes( model_data.vlon) sgrid.lon = pr.utils.wrap_longitudes(sgrid.lon) if len(numpy.shape(model_data.vlon)) <= 1: model_data.vlon, model_data.vlat = numpy.meshgrid( model_data.vlon, model_data.vlat) swath_def = pr.geometry.SwathDefinition( lons=model_data.vlon, lats=model_data.vlat) grid_def = pr.geometry.SwathDefinition(lons=sgrid.lon, lats=sgrid.lat) if p.interpolation == 'nearest': SSH_true[ ind_time[0], :] = pr.kd_tree.resample_nearest( swath_def, SSH_model, grid_def, radius_of_influence=max( p.delta_al, p.delta_ac) * 10**3, epsilon=100) else: SSH_true[ ind_time[0], :] = pr.kd_tree.resample_gauss( swath_def, SSH_model, grid_def, radius_of_influence=3 * max(p.delta_al, p.delta_ac) * 10**3, sigmas=max(p.delta_al, p.delta_ac) * 10**3, fill_value=None) if p.nadir: ngrid.lon = pr.utils.wrap_longitudes(ngrid.lon) ngrid_def = pr.geometry.SwathDefinition( lons=ngrid.lon, lats=ngrid.lat) if p.interpolation == 'nearest': SSH_true_nadir[ind_nadir_time[ 0]] = pr.kd_tree.resample_nearest( swath_def, SSH_model, ngrid_def, radius_of_influence=max( p.delta_al, p.delta_ac) * 10**3, epsilon=100) else: SSH_true_nadir[ind_nadir_time[ 0]] = pr.kd_tree.resample_gauss( swath_def, SSH_model, ngrid_def, radius_of_influence=3 * max(p.delta_al, p.delta_ac) * 10**3, sigmas=max(p.delta_al, p.delta_ac) * 10**3, fill_value=None) except: SSH_true[ind_time[0], :] = interpolate.griddata( (model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (sgrid.lon[ind_time[0], :], sgrid.lat[ind_time[0], :]), method=p.interpolation) if p.nadir: SSH_true_nadir[ ind_nadir_time[0]] = interpolate.griddata( (model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) if p.interpolation == 'nearest': if modelbox[0] > modelbox[1]: SSH_true[numpy.where( ((sgrid.lon < modelbox[0]) & (sgrid.lon > modelbox[1])) | (sgrid.lat < modelbox[2]) | (sgrid.lat > modelbox[3]))] = numpy.nan if p.nadir: SSH_true_nadir[numpy.where( ((ngrid.lon < modelbox[0]) & (ngrid.lon > modelbox[1])) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3]))] = numpy.nan else: SSH_true[numpy.where( (sgrid.lon < modelbox[0]) | (sgrid.lon > modelbox[1]) | (sgrid.lat < modelbox[2]) | (sgrid.lat > modelbox[3]))] = numpy.nan if p.nadir: SSH_true_nadir[numpy.where( (ngrid.lon < modelbox[0]) | (ngrid.lon > modelbox[1]) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3]))] = numpy.nan vindice[ind_time[0], :] = ifile if p.nadir: vindice_nadir[ind_nadir_time[0]] = ifile del ind_time, SSH_model, model_step, ind_nadir_time istep += 1 else: istep += 1 progress = mod_tools.update_progress( float(istep) / float(ntotfile * ntot), 'pass: '******'no model file provided' + ', cycle:' + str(cycle + 1)) err.make_error(sgrid, cycle, SSH_true, p) err.make_SSH_error(SSH_true, p) if p.nadir: errnad.make_error(ngrid, cycle, SSH_true_nadir, p) if p.nbeam == 1: errnad.SSH = SSH_true_nadir + errnad.nadir + err.wet_tropo1nadir else: errnad.SSH = SSH_true_nadir + errnad.nadir + err.wet_tropo2nadir #if p.file_input: del ind_time, SSH_model, model_step return SSH_true, SSH_true_nadir, vindice, vindice_nadir, time, progress
def create_Nadirlikedata(cycle, ntotfile, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=False): import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Progress bar variables are global global istep global ntot global ifile errnad.wet_tropo1nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.wt = numpy.zeros((numpy.shape(ngrid.lon)[0])) errnad.nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) SSH_true_nadir = numpy.zeros((numpy.shape(ngrid.lon)[0])) vindice = numpy.zeros(numpy.shape(ngrid.lon)) * numpy.nan ## Definition of the time in the model date1 = cycle * ngrid.cycle time = ngrid.time + date1 ## Look for satellite data that are beween step-p.timesetp/2 end setp+p.step/2 if p.file_input is True: index_filemodel = numpy.where(((time[-1] - ngrid.timeshift) >= (modeltime - p.timestep / 2.)) & ((time[0] - ngrid.timeshift) < (modeltime + p.timestep / 2.))) #[0] ## At each step, look for the corresponding time in the satellite data for ifile in index_filemodel[0]: if progress_bar: progress = mod_tools.update_progress( float(istep) / float(ntotfile * ntot), 'pass: '******'model file: ' + list_file[ifile] + ', cycle:' + str(cycle + 1)) else: progress = None ## If there are satellite data, Get true SSH from model if numpy.shape(index_filemodel)[1] > 0: ntot = ntot + numpy.shape(index_filemodel)[1] - 1 ind_nadir_time = numpy.where(((time - ngrid.timeshift) >= ( modeltime[ifile] - p.timestep / 2.)) & ( (time - ngrid.timeshift) < (modeltime[ifile] + p.timestep / 2.))) model_step = eval( 'rw_data.' + model_data.model + '(file=p.indatadir+os.sep+list_file[ifile], var=p.var)') if p.grid == 'regular': model_step.read_var() SSH_model = model_step.vvar[model_data.model_index_lat, :] SSH_model = SSH_model[:, model_data.model_index_lon] else: model_step.read_var(index=model_data.model_index) SSH_model = model_step.vvar ## - Interpolate Model data on a SWOT grid and/or along the nadir track ## if grid is regular, use interpolate.RectBivariateSpline to interpolate if p.grid == 'regular' and len(numpy.shape(model_data.vlon)) == 1: #########################TODO #To be moved to routine rw_data indsorted = numpy.argsort(model_data.vlon) model_data.vlon = model_data.vlon[indsorted] SSH_model = SSH_model[:, indsorted] lonnadir = ngrid.lon[ind_nadir_time[0]].flatten() latnadir = ngrid.lat[ind_nadir_time[0]].flatten() Teval = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, numpy.isnan(SSH_model), kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel()) SSH_model_mask = +SSH_model SSH_model_mask[numpy.isnan(SSH_model_mask)] = 0. SSH_true_ind_time = interpolate.RectBivariateSpline( model_data.vlat, model_data.vlon, SSH_model_mask, kx=1, ky=1, s=0).ev(ngrid.lon[ind_nadir_time[0]].ravel(), ngrid.lat[ind_nadir_time[0]].ravel()) SSH_true_ind_time[Teval > 0] = numpy.nan SSH_true_nadir[ind_nadir_time[0]] = SSH_true_ind_time else: ## Grid is irregular, interpolation can be done using pyresample module if it is installed or griddata function from scipy. ## Note that griddata is slower than pyresample functions. try: import pyresample as pr ngrid.lon = pr.utils.wrap_longitudes(ngrid.lon) ngrid_def = pr.geometry.SwathDefinition(lons=ngrid.lon, lats=ngrid.lat) if p.interpolation == 'nearest': SSH_true_nadir[ ind_nadir_time[0]] = pr.kd_tree.resample_nearest( swath_def, SSH_model, ngrid_def, radius_of_influence=max( p.delta_al, p.delta_ac) * 10**3, epsilon=100) else: SSH_true_nadir[ ind_nadir_time[0]] = pr.kd_tree.resample_gauss( swath_def, SSH_model, ngrid_def, radius_of_influence=3 * max(p.delta_al, p.delta_ac) * 10**3, sigmas=max(p.delta_al, p.delta_ac) * 10**3, fill_value=None) except: SSH_true_nadir[ind_nadir_time[0]] = interpolate.griddata( (model_data.vlon.ravel(), model_data.vlat.ravel()), SSH_model.ravel(), (ngrid.lon[ind_nadir_time[0]], ngrid.lat[ind_nadir_time[0]]), method=p.interpolation) if p.interpolation == 'nearest': if modelbox[0] > modelbox[1]: SSH_true_nadir[numpy.where( ((ngrid.lon < modelbox[0]) & (ngrid.lon > modelbox[1])) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3]))] = numpy.nan else: SSH_true_nadir[numpy.where( (ngrid.lon < modelbox[0]) | (ngrid.lon > modelbox[1]) | (ngrid.lat < modelbox[2]) | (ngrid.lat > modelbox[3]))] = numpy.nan vindice[ind_nadir_time[0]] = ifile istep += 1 else: if progress_bar: progress = mod_tools.update_progress( float(istep) / float(ntotfile * ntot), 'pass: '******'model file: ' + list_file[ifile] + ', cycle:' + str(cycle + 1)) else: progress = None istep += 1 errnad.make_error(ngrid, cycle, SSH_true_nadir, p) #, ind[0]) errnad.SSH = errnad.nadir + errnad.wet_tropo1nadir #del SSH_model, model_step, ind_nadir_time return SSH_true_nadir, vindice, time, progress
def run_nadir(file_param): if os.path.isfile(file_param): # basedir=os.path.dirname(swotsimulator.__file__) shutil.copyfile(file_param, 'params.py') #os.path.join(basedir,'params.py')) else: print("Error: No such file: '%s'" % file_param) sys.exit() try: import params as p except: if os.path.isfile('params.py'): print("There is a wrong entry in your params file") import params else: print("Error: No params.py module found") sys.exit() import swotsimulator.build_swath as build_swath import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools ## - Initialize some parameters values try: p.shift_lon=p.shift_lon except: p.shift_lon=None try: p.shift_time=p.shift_time except: p.shift_time=None try: model=p.model except: model='NETCDF_MODEL'; p.model= model try: p.model_nan=p.model_nan except: p.model_nan=0. try: p.SSH_factor=p.SSH_factor except: p.SSH_factor=1. #; p.SSH_factor=SSH_factor p.halfswath=0. ## - Read list of user model files """ if p.file_input: list_file = [line.strip() for line in open(p.file_input)] ## - Read model input coordinates """ if p.file_input: model_data= eval('rw_data.'+model+'(file=p.indatadir+os.sep+list_file[0])') if p.modelbox: modelbox=numpy.array(p.modelbox, dtype='float') if modelbox[0]<0: modelbox[0]=modelbox[0]+360 if modelbox[1]<0:modelbox[1]=modelbox[1]+360 else: try: modelbox=model_data.calc_box() except: print('Modelbox could not be computed, a modelbox should be given if no model file is provided') sys.exit() if p.file_input: model_data.read_coordinates() model_index=numpy.where(((modelbox[0]-1)<=model_data.vlon) & (model_data.vlon<=(modelbox[1]+1)) & ((modelbox[2]-1)<=model_data.vlat) & (model_data.vlat<=(modelbox[3]+1)))#[0] ## - Initialize random coefficients that are use to compute ## random errors following the specified spectrum errnad=build_error.errornadir(p) if p.file_coeff: if os.path.isfile(p.file_coeff[:-3]+'_nadir.nc') and (not p.makesgrid): print('\n WARNING: old random coefficient file are used') errnad.load_coeff(p) else: errnad.init_error(p) errnad.save_coeff(p) else: errnad.init_error(p) ## - Compute interpolated SSH and errors for each pass, at each ## cycle print('Compute interpolated SSH and errors:') ## load all SWOT grid files (one for each pass) ## model time step modeltime=numpy.arange(0,p.nstep*p.timestep, p.timestep) ## remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) ## initialize progress bar variables istep=0; ntot=1 ## - Loop on SWOT grid files # for ifile in p.filsat: istring=len(p.dir_setup) if not isinstance(p.filesat, list): p.filesat=[p.filesat] for filesat in p.filesat: ## load SWOT grid file ntmp, nfilesat=os.path.split(filesat[istring:-4]) if p.makesgrid: print('\n Force creation of satellite grid') orb=build_swath.makeorbit(modelbox, p, orbitfile=filesat) orb.file=p.outdatadir+os.sep+nfilesat+'_grid.nc' orb.write_orb() else: orb = rw_data.Sat_nadir(file=p.filesgrid+'.nc') cycle=0 ; x_al=[] ; al_cycle=0 ; timeshift=0 orb.load_orb(cycle=cycle,x_al=x_al, al_cycle=al_cycle, timeshift=timeshift) cycle=orb.cycle ; x_al=orb.x_al ; al_cycle=orb.al_cycle ; timeshift=orb.timeshift ## Look for model indices corresponding to the localization of the pass ## If the pass is not in the model region, continue to next loop if numpy.min(orb.lon)<1. and numpy.max(orb.lon)>359.: orb.lon[numpy.where(orb.lon>180.)]=orb.lon[numpy.where(orb.lon>180.)]-360 if p.file_input: model_data.vlon[numpy.where(model_data.vlon>180.)]=model_data.vlon[numpy.where(model_data.vlon>180.)]-360 if modelbox[0]>180.: modelbox[0]=modelbox[0]-360 if modelbox[1]>180.: modelbox[1]=modelbox[1]-360 if p.file_input: model_index=numpy.where(((numpy.min(orb.lon))<=model_data.vlon) & (model_data.vlon<=(numpy.max(orb.lon))) & ((numpy.min(orb.lat))<=model_data.vlat) & (model_data.vlat<=(numpy.max(orb.lat)))) lonmodel1d=model_data.vlon[model_index].ravel() latmodel1d=model_data.vlat[model_index].ravel() if not model_index[0].any(): continue ## Compute number of cycles needed to cover all nstep model timesteps rcycle=(p.timestep*p.nstep)/float(orb.cycle) ncycle=int(rcycle) ## Switch to (-180,180) longitude range to interpolate near 360-0 ## - Loop on all cycles for cycle in range(0,ncycle+1): ## Initialiaze errors and SSH errnad.nadir=numpy.zeros((numpy.shape(orb.x_al)[0])) errnad.wet_tropo1=numpy.zeros((numpy.shape(orb.x_al)[0])) errnad.wt=numpy.zeros((numpy.shape(orb.x_al)[0])) date1=cycle*orb.cycle SSH_true=numpy.zeros((numpy.shape(orb.x_al)[0])) #, p.nstep)) #SSH_obs=numpy.empty((numpy.shape(orb.x_al)[0])) vindice=numpy.zeros(numpy.shape(SSH_true)) ## Definition of the time in the model stime=orb.time+date1 ## Look for satellite data that are beween step-p.timesetp/2 end setp+p.step/2 if p.file_input: index=numpy.where(((stime[-1]-timeshift)>=(modeltime-p.timestep/2.)) & ((stime[0]-timeshift)<(modeltime+p.timestep/2.)) )#[0] ## At each step, look for the corresponding time in the satellite data for ifile in index[0]: ntot=1 mod_tools.update_progress(float(istep)/float(p.nstep*ntot*numpy.shape(p.filesat)[0]), 'Sat: '+ filesat[istring:], 'model file: '+list_file[ifile] +', cycle:'+str(cycle+1)) #mod_tools.update_progress(float(istep)/float(p.nstep*ntot), 'Sat: '+ filesat[istring:], 'model file: '+list_file[ifile] +', cycle:'+str(cycle+1)) ## If there are satellite data, Get true SSH from model if numpy.shape(index)[1]>0: ntot=ntot+numpy.shape(index)[1]-1 #if numpy.shape(index)[1]>1: ind=numpy.where(((stime-timeshift)>=(modeltime[ifile]-p.timestep/2.)) & ((stime-timeshift)<(modeltime[ifile]+p.timestep/2.)) ) exec('model_step=rw_data.'+model+'(file=p.indatadir+os.sep+list_file[ifile], var=p.var)') model_step.read_var(index=model_index) SSH_model=model_step.vvar SSH_true[ind[0]]=interpolate.griddata((lonmodel1d, latmodel1d), SSH_model.ravel(), (orb.lon[ind[0]], orb.lat[ind[0]]), method=p.interpolation) if p.interpolation=='nearest': if modelbox[0]>modelbox[1]: SSH_true[numpy.where(((orb.lon<modelbox[0]) & (orb.lon>modelbox[1])) | (orb.lat<modelbox[2]) | (orb.lat>modelbox[3]))] = numpy.nan else: SSH_true[numpy.where((orb.lon<modelbox[0]) | (orb.lon>modelbox[1]) | (orb.lat<modelbox[2]) | (orb.lat>modelbox[3]))] = numpy.nan #SSH_true[numpy.where((orb.lon<modelbox[0]) | (orb.lon>modelbox[1]) | (orb.lat<modelbox[2]) | (orb.lat>modelbox[3]))] = numpy.nan vindice[ind[0]]=ifile del ind, SSH_model, model_step istep+=1 else: istep+=1 mod_tools.update_progress(float(istep)/float(rcycle*numpy.shape(p.filesat)[0]), 'Sat: '+ filesat[istring:], 'no model file provide '+', cycle:'+str(cycle+1)) SSH_true[SSH_true==0]=numpy.nan errnad.make_error(orb, cycle, SSH_true, p) #, ind[0]) if p.wet_tropo: errnad.SSH=SSH_true+errnad.nadir+errnad.wet_tropo1 #make_SSH_errornadir(SSH_true,p) else: errnad.SSH=SSH_true+errnad.nadir #make_SSH_errornadir(SSH_true,p) ## Save outputs in a netcdf file if vindice.any() or not p.file_input: file_output=p.file_output+'_c'+str(cycle+1).zfill(2)+'.nc' Output=rw_data.Sat_nadir(file=file_output, lon=(orb.lon+360)%360, lat=orb.lat, time=stime, x_al=orb.x_al, cycle=orb.cycle) Output.write_data(SSH_model=SSH_true, index=vindice, nadir_err=errnad.nadir, SSH_obs=errnad.SSH, pd_err_1b=errnad.wet_tropo1,pd=errnad.wt) #, ncycle=cycle) del stime if p.file_input: del index #orb.lon=(orb.lon+360)%360 #if p.file_input: model_data.vlon=(model_data.vlon+360)%360 #modelbox[0]=(modelbox[0]+360)%360 #modelbox[1]=(modelbox[1]+360)%360 del orb ## - Write Selected parameters in a txt file rw_data.write_params(p,p.outdatadir+os.sep+'orbit_simulator.output') print("\n Simulated orbit files have been written in " + p.outdatadir) print("----------------------------------------------------------")
def run_nadir(file_param): if os.path.isfile(file_param): # basedir=os.path.dirname(swotsimulator.__file__) shutil.copyfile(file_param, 'params.py') #os.path.join(basedir,'params.py')) else: print("Error: No such file: '%s'" % file_param) sys.exit() try: import params as p except: if os.path.isfile('params.py'): print("There is a wrong entry in your params file") import params else: print("Error: No params.py module found") sys.exit() import swotsimulator.build_swath as build_swath import swotsimulator.rw_data as rw_data import swotsimulator.build_error as build_error import swotsimulator.mod_tools as mod_tools import swotsimulator.const as const ## - Initialize some parameters values try: p.shift_lon = p.shift_lon except: p.shift_lon = None try: p.shift_time = p.shift_time except: p.shift_time = None try: model = p.model except: model = 'NETCDF_MODEL' p.model = model try: p.model_nan = p.model_nan except: p.model_nan = 0. try: p.SSH_factor = p.SSH_factor except: p.SSH_factor = 1. #; p.SSH_factor=SSH_factor try: p.nadir = p.nadir except: p.nadir = True try: p.grid = p.grid except: p.grid = 'regular' p.karin = False p.phase = False p.roll = False p.baseline_dilation = False p.timing = False p.halfswath = 60. ## - Progress bar variables are global global istep global ntot ## - Read list of user model files """ if p.file_input: list_file = [line.strip() for line in open(p.file_input)] ## - Read model input coordinates ''' # if no modelbox is specified (modelbox=None), the domain of the input data is taken as a modelbox # coordinates from the region defined by modelbox are selected if p.file_input: model_data = eval('rw_data.' + model + '(file=p.indatadir+os.sep+list_file[0])') if p.modelbox: modelbox = numpy.array(p.modelbox, dtype='float') ## Use convert to 360 data modelbox[0] = (modelbox[0] + 360) % 360 if modelbox[1] != 360: modelbox[1] = (modelbox[1] + 360) % 360 else: if p.file_input: modelbox = model_data.calc_box() else: print('modelbox should be provided if no model file is provided') sys.exit() if p.file_input: model_data.read_coordinates() ## Select model data in the region modelbox if p.grid == 'regular': model_data.model_index_lon = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)))[0] model_data.model_index_lat = numpy.where( ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1)))[0] model_data.vlon = model_data.vlon[model_data.model_index_lon] model_data.vlat = model_data.vlat[model_data.model_index_lat] else: model_data.model_index = numpy.where( ((modelbox[0] - 1) <= model_data.vlon) & (model_data.vlon <= (modelbox[1] + 1)) & ((modelbox[2] - 1) <= model_data.vlat) & (model_data.vlat <= (modelbox[3] + 1))) #[0] model_data.model = model model_data.vloncirc = numpy.rad2deg(numpy.unwrap(model_data.vlon)) ## Ugly trick when model box is [0 360] to avoid box being empty (360=0%360) if modelbox[1] == 0: modelbox[1] = 359.99 ## - Initialize random coefficients that are used to compute ## random errors following the specified spectrum err, errnad = load_error(p) ## - Compute interpolated SSH and errors for each pass, at each ## cycle print('Compute interpolated SSH and errors:') ## Model time step modeltime = numpy.arange(0, p.nstep * p.timestep, p.timestep) ## Remove the grid from the list of model files if p.file_input: list_file.remove(list_file[0]) ## Initialize progress bar variables istep = 0 ntot = 1 ## Initialize list of satellites istring = len(p.dir_setup) if not isinstance(p.filesat, list): p.filesat = [p.filesat] for filesat in p.filesat: ## Select satellite ntmp, nfilesat = os.path.split(filesat[istring:-4]) ## Make satellite orbit grid if p.makesgrid: print('\n Force creation of satellite grid') ngrid = build_swath.makeorbit(modelbox, p, orbitfile=filesat) ngrid.file = p.outdatadir + os.sep + nfilesat + '_grid.nc' ngrid.write_orb() ngrid.ipass = nfilesat ngrid.gridfile = p.outdatadir + os.sep + nfilesat + '_grid.nc' else: ## To be replaced by load_ngrid ngrid = rw_data.Sat_nadir(file=p.filesgrid + '.nc') ngrid.ipass = nfilesat ngrid.gridfile = p.outdatadir + os.sep + nfilesat + '_grid.nc' cycle = 0 x_al = [] al_cycle = 0 timeshift = 0 ngrid.load_orb(cycle=cycle, x_al=x_al, al_cycle=al_cycle, timeshift=timeshift) ngrid.loncirc = numpy.rad2deg(numpy.unwrap(ngrid.lon)) #ngrid=load_ngrid(sgridfile, p) ## Select model data around the swath to reduce interpolation cost in griddata ## - Generate SWOT like and nadir-like data: ## Compute number of cycles needed to cover all nstep model timesteps if p.file_input: model_index = numpy.where( ((numpy.min(ngrid.lon)) <= model_data.vlon) & (model_data.vlon <= (numpy.max(ngrid.lon))) & ((numpy.min(ngrid.lat)) <= model_data.vlat) & (model_data.vlat <= (numpy.max(ngrid.lat)))) rcycle = (p.timestep * p.nstep) / float(ngrid.cycle) ncycle = int(rcycle) ## Loop on all cycles for cycle in range(0, ncycle + 1): if ifile > (p.nstep / p.timestep + 1): break ## Create SWOT-like and Nadir-like data if not p.file_input: model_data = [] SSH_true_nadir, vindice, time, progress = create_Nadirlikedata( cycle, numpy.shape(p.filesat)[0] * rcycle, list_file, modelbox, ngrid, model_data, modeltime, errnad, p, progress_bar=True) #SSH_true_nadir, vindice_nadir=create_Nadirlikedata(cycle, sgrid, ngrid, model_data, modeltime, err, errnad, p) ## Save outputs in a netcdf file ngrid.gridfile = filesat if (~numpy.isnan(vindice)).any() or not p.file_input: err = errnad err.wtnadir = numpy.zeros((1)) err.wet_tropo2nadir = numpy.zeros((1)) save_Nadir(cycle, ngrid, errnad, err, p, time=time, vindice_nadir=vindice, SSH_true_nadir=SSH_true_nadir) del time #if p.file_input: del index ngrid.lon = (ngrid.lon + 360) % 360 if p.file_input: model_data.vlon = (model_data.vlon + 360) % 360 modelbox[0] = (modelbox[0] + 360) % 360 modelbox[1] = (modelbox[1] + 360) % 360 del ngrid if progress != 1: progress = mod_tools.update_progress(1, 'All passes have been processed', '') ## - Write Selected parameters in a txt file rw_data.write_params(p, p.outdatadir + os.sep + 'nadir_simulator.output') print("\n Simulated orbit files have been written in " + p.outdatadir) print("----------------------------------------------------------")