def get_data_on_vertical_segment(self, var_name, record, point): """ Extract values for each plane of a 2d points in telemac-3d result file for the given variable @param point (numpy.array) Point of extraction @param varname (string) Name of variable for which to extract data @param record (int) Number of desired record @returns (numpy.array) """ if self.get_mesh_dimension() != 3: raise TelemacException("Action possible only on 3d mesh") if len(point) != 2: raise TelemacException('Warning the extraction point '\ 'must be 2d') nplan = self.nplan res = np.zeros(nplan) for plan in range(self.nplan): values = self.get_data_on_horizontal_plane(\ var_name, record, plan) data_interp = mtri.LinearTriInterpolator(self.tri, values) res[plan] = data_interp(point[0], point[1]) return res
def get_data_on_horizontal_slice(\ self, varname, record, zslices, nplanref=None): """ Extract values of plan in telemac-3d result file for the given variable @param zslice (numpy.array) Elevation of the slice @param record (int) Number of desired record @param nplanref (int) Number of reference plane @param varname (string) Name of variable for which to extract data @returns (numpy.array) """ if self.get_mesh_dimension() != 3: raise TelemacException("Action possible only on 3d mesh") if isinstance(zslices, list) or isinstance(zslices, np.ndarray): if zslices.ndim > 1: raise TelemacException('Warning the slice coordinate'\ 'must be 1d') res = np.zeros(((self.npoin2), len(zslices)), dtype=np.float64) zslices_list = zslices elif isinstance(zslices, int): res = np.zeros(((self.npoin2), zslices), dtype=np.float64) zslices_list = [zslices] else: raise TelemacException('Unknown zslices type') zref = np.zeros((self.npoin2), dtype=np.float64) if 'ELEVATION Z' in self.varnames: if nplanref is not None: zref = self.get_data_on_horizontal_plane(\ 'ELEVATION Z', record, nplanref) values_elevation = self.get_data_value('ELEVATION Z', record) values_elevation = values_elevation.reshape( self.nplan, self.npoin2) values_var = self.get_data_value(varname, record) values_var = values_var.reshape(self.nplan, self.npoin2) for izs, zslice in enumerate(zslices_list): zslice = zref + zslice for j in range(self.npoin2): res[j, izs] = float('nan') for i in range(self.nplan - 1): if values_elevation[i, j] <= zslice[j] and \ zslice[j] <= values_elevation[i+1, j]: shz = (zslice[i]-values_elevation[i, j])/\ max((values_elevation[i+1, j] \ - values_elevation[i, j]), 1.0e-6) res[j, izs] = (1.0-shz)*values_var[i, j]+shz*\ values_var[i+1, j] break else: raise TelemacException('Warning the dimension of the result '\ 'file is not 3 ELEVATION Z is missing') if isinstance(zslices, list) or isinstance(zslices, np.ndarray): return res elif isinstance(zslices, int): return res[:, 0]
def get_data_on_horizontal_plane(self, varname, record, plane_number): """ Extract values of one plane in telemac-3d result file for the given variable @param varname (string) Name of variable for which to extract data @param record (int) Number of desired record @param plane_number (int) Number of desired plane @returns (numpy.array) """ if self.get_mesh_dimension() != 3: raise TelemacException("Action possible only on 3d mesh") values = self.get_data_value(varname, record) if plane_number < 0 or plane_number >= self.nplan: raise TelemacException(\ 'Wrong plane number {} should be in [0, {}]'\ .format(plane_number, self.nplan-1)) start = plane_number * self.npoin2 end = (plane_number + 1) * self.npoin2 extracted_values = values[start:end] return extracted_values
def get_data_on_points(self, varname, record, points): """ Extract values on points in telemac result file (2D or 3D) for the given variable for one record @param varname (string) Name of variable for which to extract data @param record (int) Number of desired record to extract @param points list of numpy.array containing points of extraction @returns (numpy.array) """ res = float('nan') * np.ones((len(points)), dtype=np.float64) if len(np.shape(np.array(points))) != 2: raise TelemacException('Warning problem with the list of '\ 'extraction points') # dimension of the computation result dim = np.shape(np.array(points))[1] if dim == 2: res = self._get_data_on_2d_points(varname, record, points) elif dim == 3: res = self._get_data_on_3d_points(varname, record, points) else: raise TelemacException('Warning problem with the dimension of '\ 'extraction points') return res
def subdivide(options): """ Subdivide a mesh """ if not options.freplace: if len(options.args) != 2: raise TelemacException(\ '\nThe code "subdivide" ' '(without --replace) here ' 'requires 2 file names\n') slf_file = options.args[0] out_file = options.args[1] else: if len(options.args) != 1: raise TelemacException(\ '\nThe code "subdivide" (with --replace) ' 'here requires 1 file name at a time\n') slf_file = options.args[0] out_file = "subdivide-tmp.slf" slf_file = path.realpath(slf_file) if not path.exists(slf_file): raise TelemacException(\ '\nCould not find' ' the file named: {}'.format(slf_file)) print('\n\nSubdividing ' + path.basename(slf_file) + ' within ' + \ path.dirname(slf_file) + '\n'+'~'*72+'\n') slf = SubSelafin(slf_file) slf.put_content(out_file) if options.freplace: move_file(out_file, slf_file)
def run_damocles(exe_path, parame_file, log_file=''): """ Running the damocles executable @param exe_path Path the damocles executable @param parame_file Path to the input aprameters file @param log_file Redirecting ouput to that file if present """ if not path.exists(exe_path): raise TelemacException("You need to compile damocles to use it...") # Run Fortran program mes = Messages(size=10) try: if log_file == '': print("%s < %s " % (exe_path, parame_file)) _, code = mes.run_cmd("%s < %s" % (exe_path, parame_file), False) else: print("%s < %s > %s" % (exe_path, parame_file, log_file)) _, code = mes.run_cmd( "%s < %s > %s" % (exe_path, parame_file, log_file), False) except OSError as exc: raise TelemacException(exc.strerror) if code != 0: raise TelemacException([\ {'name':'damocles', 'msg':'Could not execute damocles'\ +'\n\nHere is the log:\n' +'\n'.join(get_file_content(log_file)) }])
def move_file2file(src, dest): """ Move file to file @param src (string) source file @param dest (string) target file """ if dest == src: return if path.exists(dest): try: remove(dest) except BaseException: time.sleep(5) # /!\ addition for windows operating system try: remove(dest) except BaseException as excpt: raise TelemacException( 'I could not remove your existing file: ' + dest) if path.exists(src): try: shutil.move(src, dest) except BaseException: time.sleep(5) # /!\ addition for windows operating system try: shutil.move(src, dest) except BaseException as excpt: raise TelemacException('I could not move your file: ' + src + '\n ... maybe the detination exists?')
def build_box(blcorner, trcorner): """ Define the box for the data request @param blcorner (string) Bottom Left cnorner @param trcorner (string) Top Right corner @return The model box """ modelbox = [[], []] if blcorner is not None: x, y = literal_eval(blcorner) modelbox[0].append(str(x)) modelbox[0].append(str(y)) else: raise TelemacException( '... could not find your bounding box bottom left' 'corner. Please use --bl option (, delimited, no ' 'spaces).\n\n') if trcorner is not None: x, y = literal_eval(trcorner) modelbox[1].append(str(x)) modelbox[1].append(str(y)) else: raise TelemacException( '... could not find your bounding box top right ' 'corner. Please use --tr option (, delimited, no ' 'spaces).\n\n') return modelbox
def move_file(src, dest): """ Move file to directory @param src (string) source file @param dest (string) target directory """ if path.exists(path.join(dest, path.basename(src))): try: remove(path.join(dest, path.basename(src))) except BaseException: time.sleep(5) # /!\ addition for windows operating system try: remove(path.join(dest, path.basename(src))) except BaseException as excpt: raise TelemacException(\ 'I could not remove your existing file: '+src) if path.exists(src): try: shutil.move(src, dest) except BaseException: time.sleep(5) # /!\ addition for windows operating system try: shutil.move(src, dest) except BaseException as excpt: raise TelemacException(\ 'I could not move your file: ' + src + '\n ... maybe the detination exists?')
def build_period(tfrom, tstop): """ Define the time period for the data request @param tfrom (string) First date (ex "1972-13-07") @param tstop (string) Last date (ex "1980-12-31") """ period = [[], []] if tfrom != None: for i in tfrom.split('-'): period[0].append(i) else: raise TelemacException(\ '... could not find your from date. ' 'Please use --from option ' '(- delimited, no spaces).\n\n') if tstop != None: for i in tstop.split('-'): period[1].append(i) else: raise TelemacException(\ '... could not find your stop date. ' 'Please use --stop option ' '(- delimited, no spaces).\n\n') return period
def hycom2srf(tfrom, tstop, blcorner, trcorner, root_name, only_2d): """ Convertion form HYCOM data to Serafin format """ # Arbitrary 6-day period period = [[], []] if tfrom != None: for i in tfrom.split('-'): period[0].append(int(i)) else: raise TelemacException(\ '... could not find your from date. ' 'Please use --from option ' '(- delimited, no spaces).\n\n') if tstop != None: for i in tstop.split('-'): period[1].append(int(i)) else: raise TelemacException(\ '... could not find your stop date. ' 'Please use --stop option ' '(- delimited, no spaces).\n\n') # arbitrary box (small pieve of the atlantic side of Mexico) modelbox = [[], []] if blcorner != None: for i in blcorner.split(','): modelbox[0].append(int(i)) else: raise TelemacException(\ '... could not find your bounding box bottom left corner. ' 'Please use --bl option (, delimited, no spaces).\n\n') if trcorner != None: for i in trcorner.split(','): modelbox[1].append(int(i)) else: raise TelemacException(\ '... could not find your bounding box top right corner. ' 'Please use --tr option (, delimited, no spaces).\n\n') # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Convert to Selafin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print('\n\n' + '~' * 72 + '\n') print('\nProcessing header (mesh, connectivity, etc.)\n') hy2slf = HYCOM(period) hy2slf.get_header_hycom(modelbox) print('\n\n' + '~' * 72 + '\n') print('\nProcessing core variables (time record, variables, etc.)\n') tic = time.time() print('\nExtraction start time: '+\ time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tic))) hy2slf.put_content(root_name, only_2d) toc = time.time() print('\nExtraction end time: '+\ time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(toc))) print('___________\nDuration: ' + str(int(toc - tic)) + ' seconds\n')
def _parse_cas(self): """ Parse the steering file and identify (key, value) And updates self.values according to the pairs identified """ lines = [] # ~~ clean ending empty lines with open(self.file_name, 'r') as f: for line in f.readlines(): # Remove trailing spaces (left and right) and \n line = line.strip(' ').rstrip('\n') # not adding empty lines if line != '': # Skipping &key (&ETA, &FIN...) if line[0] == '&': continue else: lines.append(line) # ~~ clean comments core = [] for line in lines: line = line.replace('"""', "'''")\ .replace('"', "'")\ .replace("''", '"') proc = re.match(KEY_COMMENT, line+'/') line = proc.group('before').strip() + ' ' proc = re.match(EMPTY_LINE, line) if not proc: core.append(line) # Creates a one line of the cleaned up steering cas_stream = (' '.join(core)) # ~~ Matching keword -> values while cas_stream != '': # ~~ Matching keyword proc = re.match(KEY_EQUALS, cas_stream) if not proc: raise TelemacException(\ ' Error while parsing steering file {} ' 'incorrect line:\n{}'\ .format(self.file_name, cas_stream[:100])) keyword = proc.group('key').strip() cas_stream = proc.group('after') # still hold the separator # ~~ Matching value proc = re.match(VAL_EQUALS, cas_stream) if not proc: raise TelemacException('No value to keyword '+keyword) val = [] # The value can be on multiple lines while proc: if proc.group('val') == '"': val.append('') else: val.append(proc.group('val').replace("'", '')) cas_stream = proc.group('after') # still hold the separator proc = re.match(VAL_EQUALS, cas_stream) # Updating the value with the last one read self.values[keyword] = val
def read_cfg(self): """ Read the content of the config file and extract all cfgs, and their key/values -- Returns a dictionary of all configs in the files that are highlighted in [Configurations] """ bypass = False # ~~ Read Configuration File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cfgfile = configparser.RawConfigParser() try: cfgfile.read(self.cfg_file, encoding='utf-8') except configparser.Error as xcpt: raise TelemacException(\ 'Error while reading {}'.format(self.cfg_file)+str(xcpt)) # ~~ Read Config Names ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cfgs = cfgfile.get('Configurations', 'configs') if cfgs == '': raise TelemacException(\ '\nPlease specify appropriate configuration names for ' 'key [Configurations] in the config file\n') # ~~ Filter Config Names ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cfgnames = cfgs.split() if self.cfgname != '': if self.cfgname not in cfgnames: print('\nNot able to find your configuration [{}]' ' in the configuration file: {}'.format( self.cfgname, self.cfg_file)) if bypass: print(' ... will try to gess the configuration from ' 'the general keys and move on ...') else: err = '\n ... use instead:\n' for cfg in cfgnames: err += ' +> {}\n'.format(cfg) raise TelemacException(err) cfgnames = [self.cfgname] else: # If no configuration given taking the first one self.cfgname = cfgnames[0] # ~~ Verify presence of configs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for cfg in cfgnames: if cfg not in cfgfile.sections(): raise TelemacException(\ '\nNot able to find the configuration [{}] ' 'in the configuration file: {}'.format(cfg, self.cfg_file)) # ~~ Read General ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if 'general' in cfgfile: self.general = dict(cfgfile.items('general')) else: self.general = {} # ~~ Loads Configurations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.configs = {} for cfg in cfgnames: if cfg in cfgfile: self.configs.update({cfg: dict(cfgfile.items(cfg))}) else: self.configs.update({cfg: {}})
def get_xyn(file_name): # TODO: Read the whole header, for the time being head is copied # over # TODO: Read multiple variables depending on type and on a list # ~~ Get all ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ core = get_file_content(file_name) # ~~ Parse head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ icore = 0 file_type = None while re.match(KEN_HEADER, core[icore]): # ~~> instruction FileType proc = re.match(ASC_FILE_TYPE, core[icore]) if proc: file_type = proc.group('type').lower() # ... more instruction coming ... icore += 1 head = core[0:icore] if file_type is None: proc = re.match(VAR_3DBL, core[icore]+' ') if not proc: proc = re.match(VAR_2DBL, core[icore]+' ') if not proc: raise TelemacException( '\nCould not parse the first record: ' '{}'.format(core[icore])) else: file_type = 'xy' else: file_type = 'xyz' # /!\ icore starts the body # ~~ Parse body ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # This is also fairly fast, so you might not need a progress bar xyz = [] # ; pbar = ProgressBar(maxval=len(core)).start() while icore < len(core): if file_type == 'xy': proc = re.match(VAR_2DBL, core[icore]+' ') if not proc: raise TelemacException( '\nCould not parse the following xyz record: ' '{}'.format(core[icore])) xyz.append([float(proc.group('number1')), float(proc.group('number2'))]) elif file_type == 'xyz': proc = re.match(VAR_3DBL, core[icore]+' ') if not proc: raise TelemacException( '\nCould not parse the following xyz record: ' '{}'.format(core[icore])) xyz.append([float(proc.group('number1')), float(proc.group('number2')), float(proc.group('number3'))]) icore += 1 # pbar.finish() return head, file_type, xyz
def __init__(self, dates): try: from pydap.client import open_url except Exception as excpt: raise TelemacException( '... you are in bad luck !\n' ' ~> you need the pydap library unzipped locally\n' '{}'.format(excpt)) # ~~~~ Initialisation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.moddates = [datetime(*dates[0]), datetime(*dates[1])] jcope2vars = ['el', 'itime', 's', 'u', 'v'] # /!\ unknown convertion of time records into dates jcope2date = [1993, 1, 1] jcope2root = 'http://apdrc.soest.hawaii.edu/dods/public_data/FRA-JCOPE2' self.slf2d = None self.slf3d = None self.jcope2ilon = None self.jcope2ilat = None self.zplan = None self.mask2 = None self.mask3 = None # ~~~~ Time records ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print(' +> Extract JCOPE2 time records\n') self.experiments = [] experiment = {} # /!\ only one time period covered at this stage for jvar in jcope2vars: jcope2url = jcope2root + '/' + jvar jcope2data = open_url(jcope2url) nit = jcope2data['time'].shape[0] # /!\ the following print statement requires __future__ print(' x ' + str(nit) + ' records from ' + jcope2url, end='') its = [] ats = [] for itime in range(nit): date = datetime(jcope2date[0], jcope2date[1], jcope2date[2])+\ timedelta(itime) if itime == 0: print(' from: ' + str(date), end='') if itime == nit - 1: print(' to: ' + str(date)) if self.moddates[0] <= date and date <= self.moddates[1]: its.append(itime) ats.append(date) if its != []: for ivar in list(jcope2data.keys()): if ivar not in ['time', 'lev', 'lat', 'lon']: experiment.update({ivar: jcope2data[ivar]}) else: raise TelemacException(\ '... I could not find the time to do your work\n' ' ~> you may need to select a different time period\n') self.experiments.append((experiment, nit, its, ats)) print('\n')
def get_lqd(file_name): # ~~ Get all ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ core = get_file_content(file_name) # ~~ Parse head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ icore = 0 while re.match(LQD_HEADER, core[icore]): icore += 1 head = core[0:icore] # /!\ icore starts the body # ~~ Parse variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jcore = icore + 1 while icore < len(core) and jcore < len(core): if re.match(LQD_HEADER, core[icore]): icore += 1 jcore += 1 continue if re.match(LQD_HEADER, core[jcore]): jcore += 1 continue core[icore].replace(',', ' ') core[jcore].replace(',', ' ') # ~~> Variable header if core[icore].split()[0].upper() != 'T': raise TelemacException(\ '\nThought I would find T for this LQD file on ' 'this line: {}'.format(core[icore])) if len(core[icore].split()) != len(core[jcore].split()): raise TelemacException(\ '\nThought I to corresponding units for this LQD file on ' 'this line: {}'.format(core[jcore])) vrs = zip(core[icore].upper().split(), core[jcore].upper().split()) # ~~ Size valid values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ icore = jcore + 1 while icore < len(core): if not re.match(LQD_HEADER, core[jcore]): icore += 1 # ~~ Parse body ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # This is also fairly fast, so you might not need a progress bar time = np.zeros(jcore - icore) z = np.zeros(len(vrs) - 1, jcore - icore) itime = 0 for icore in core[jcore + 1:]: if re.match(LQD_HEADER, icore): continue values = icore.replace(',', ' ').split() time[itime] = float(values[0]) for ivar in range(len(values[1:])): z[itime][ivar] = float(values[ivar]) return head, vrs[1:], time, z
def get(self, varname, i=0, j=0, k=0): """ Get the value of a variable of Mascaret @param varname (str) Name of the variable @param i (int) index on first dimension @param j (int) index on second dimension @param k (int) index on third dimension @return scalar value """ value = None vartype, _, _, ndim = self.get_type_var(varname) # Calling get_var_size with index=i in case of tracer dim1, dim2, dim3 = self.get_var_size(varname, i) # Checking that index are within bound if ndim >= 1: if not 0 <= i < dim1: raise TelemacException("i=%i is not within [0,%i]" % (i, dim1)) index_i = i + 1 else: index_i = 0 if ndim >= 2: if not 0 <= j < dim2: raise TelemacException("j=%i is not within [0,%i]" % (j, dim2)) index_j = j + 1 else: index_j = 0 if ndim == 3: if not 0 <= k < dim3: raise TelemacException("k=%i is not within [0,%i]" % (k, dim3)) index_k = k + 1 else: index_k = 0 # Getting value depending on type if b'DOUBLE' in vartype: value = self.get_double(varname, index_i, index_j, index_k) elif b'INT' in vartype: value = self.get_int(varname, index_i, index_j, index_k) elif b'STRING' in vartype: value = self.get_string(varname, index_i, index_j, index_k) elif b'BOOL' in vartype: value = self.get_bool(varname, index_i, index_j, index_k) else: raise TelemacException("Unknown data type %s for %s" % (vartype, varname)) return value
def set(self, varname, value, i=0, j=0, k=0): """ Set the value of a variable of Mascaret @param varname (str) Name of the variable @param value (str/float/int) to set @param i (int) index on first dimension @param j (int) index on second dimension @param k (int) index on third dimension """ vartype, _, modifiable, ndim = self.get_type_var(varname) dim1, dim2, dim3 = self.get_var_size(varname, i) # Check modifiable value if not modifiable: raise TelemacException("Variable %s is readonly" % varname) # Checking that index are within bound if ndim >= 1: if not 0 <= i < dim1: raise TelemacException("i=%i is not within [0,%i]" % (i, dim1)) index_i = i + 1 else: index_i = 0 if ndim >= 2: if not 0 <= j < dim2: raise TelemacException("j=%i is not within [0,%i]" % (i, dim2)) index_j = j + 1 else: index_j = 0 if ndim == 3: if not 0 <= k < dim3: raise TelemacException("k=%i is not within [0,%i]" % (i, dim3)) index_k = k + 1 else: index_k = 0 # Getting value depending on type if b"DOUBLE" in vartype: self.set_double(varname, value, index_i, index_j, index_k) elif b"INT" in vartype: self.set_int(varname, value, index_i, index_j, index_k) elif b"STRING" in vartype: self.set_string(varname, value, index_i, index_j, index_k) elif b"BOOL" in vartype: self.set_bool(varname, value, index_i, index_j, index_k) else: raise TelemacException("Unknown data type %s for %s" % (vartype, varname))
def _check_choix(self): """ Check if the keyword value is in the list of choix """ for key, value in self.values.items(): # If empty value doing nothing if value in ['', []]: continue # Check if we have a keyword with choices choix = 'CHOIX1' if self.lang == 'en' else 'CHOIX' if choix in self.dico.data[key]: list_choix = self.dico.data[key][choix] # Special treatment for grapchi outputs like keywords if key in SPECIAL: if key == 'COUPLING WITH': list_val = value.split(";") else: list_val = value.split(",") for val in list_val: tmp_val = str(val.strip(' 0123456789*')) new_val = 'k' + tmp_val + 'i' new_val2 = 'k' + tmp_val new_val3 = tmp_val + 'i' # Handling case of Tracer lists such as T1, T* ... # Special case for gaia where you have stuff like kSi # and kES where k and i are number or * if not (str(val).strip(' ') in list_choix or str(val).rstrip('123456789*') in list_choix or new_val in list_choix or new_val2 in list_choix or new_val3 in list_choix): raise TelemacException( "In {}: \n".format(self.file_name) + "The value for {} ({})is not" " among the choices: \n{}".format( key, val, list_choix)) elif isinstance(value, list): for val in value: if str(val).strip(' ') not in list_choix: raise TelemacException( "In {}: \n".format(self.file_name) + "The value for {} ({})is not among" " the choices: \n{}".format( key, val, list_choix)) else: if str(value).strip(' ') not in list_choix: raise TelemacException( "In {}: \n".format(self.file_name) + "The value for {} ({})is not among the choices: \n{}" .format(key, value, list_choix))
def chop(options): """ Chopping of a file """ root_file = None if not options.freplace: if not options.parallel: if len(options.args) != 2: raise TelemacException(\ '\nThe code "chop" (without --replace) ' 'here requires 2 file names\n') slf_files = [options.args[0]] out_file = options.args[1] else: if len(options.args) != 3: raise TelemacException(\ '\nThe code "chop" (without --replace) ' 'here requires 2 file names and ' '1 file root name for the partition\n') slf_files = [options.args[0]] root_file = options.args[1] out_file = options.args[2] else: slf_files = options.args out_file = "chop-tmp.slf" for slf_file in slf_files: slf_file = path.realpath(slf_file) if not path.exists(slf_file): raise TelemacException(\ '\nCould not find the file named: {}'.format(slf_file)) print('\n\nChoping ' + path.basename(slf_file) + ' within ' + \ path.dirname(slf_file) + '\n'+'~'*72+'\n') vrs = options.xvars if options.xvars != None: vrs = clean_quotes(options.xvars.replace('_', ' ')) times = (int(options.tfrom), int(options.tstep), int(options.tstop)) slf = ChopSelafin(slf_file, times=times, vrs=vrs, root=root_file) if options.eswitch: slf.alter_endian() if options.fswitch: slf.alter_float() slf.put_content(out_file) if options.freplace: move_file(out_file, slf_file)
def generate_doxygen(doxydoc, verbose): """ Generate the Doxygen documentation (In html) for the Python and the sources @param doxydoc name of the doxygen folder to use (doxydocs or doxypydocs) @param verbose If True display doxygen listing """ if doxydoc == "doxydocs": # Checking that the converter is compiled converter_path = path.join(CFGS.get_root(), 'optionals', 'addons', 'to_f90') if not path.exists(path.join(converter_path, 'f77_to_f90')): raise TelemacException( "You need to compile the converter in :\n"+converter_path) # Compiling sources doxygen doxy_dir = path.join(CFGS.get_root(), 'documentation', doxydoc) doxy_file = path.join(doxy_dir, 'Doxyfile') compile_doxygen(doxy_file, verbose)
def plot_var(res, var, record=-1, time=None, add_mesh=False, fig_name=''): """ Plot a scalar map for the given variable and time record @param res (TelemacFile) Structure to file from which data will be read @param var (str) Name of the variable to plot @param record (str) Record to plot @param time (str) If >= 0.0 will get nearest record to that time (This overwrites record) @param add_mesh (boolean) If True overlay the mesh on top of the scalar map @param fig_name (str) If not empty save the plot in that file instead of showing it """ # If time is positive searched for record if time is not None: record = res.get_closest_record(time) time = res.times[record] else: time = res.times[record] if var not in res.varnames: raise TelemacException("{} is not in :\n{}".format(var, res.varnames)) vnv_plot2d(var, res, plot_mesh=add_mesh, record=record, filled_contours=True, aspect_ratio="equal", fig_name=fig_name)
def download_ecmwf(self): result = self.connection.result() file_name = self.request.get("target") # ~> tries connecting 3 times before stopping tries = 0 while True: # ~> downloading file by blocks http = urlopen(result["href"]) f = open(file_name, "wb") ibar = 0 pbar = ProgressBar(maxval=result["size"]).start() while True: chunk = http.read(1024 * 1024) if not chunk: break f.write(chunk) ibar += len(chunk) pbar.update(ibar) f.flush() f.close() pbar.finish() # ~> have I got everything ? if ibar == result["size"]: break if tries == 3: raise TelemacException(" ... exhausted the number " "of download trials.\nYou may wish " "to attempt this again later.") print(" ... trying to download the data once more ...") tries += 1
def generate_notebook_pdf(doc_dir, notebook_dir): """ Generate an html layout of the notebooks using ipython nbconvert Than coying back the file into doc_dir @param doc_dir (string) Path to the folder that will contain the html version of the docuemntation @param notebook_dir (string) Path to the notebooks """ # Creating doc folder if necessary if not path.exists(doc_dir): mkdir(doc_dir) # Running convertion in notebook folder # Gathering all html files for root, _, files in walk(notebook_dir): for ffile in files: if ffile.endswith("ipynb"): # Skipping notebook tmp folders if ".ipynb_checkpoint" in root: continue notebook = path.join(root, ffile) cmd = "jupyter nbconvert --to pdf --output-dir={} {}"\ .format(doc_dir, notebook) print(" ~> Converting "+ffile) # Running convertion mes = Messages(size=10) tail, code = mes.run_cmd(cmd, bypass=False) if code != 0: raise TelemacException('nbconvert failed\n {}'.format(tail))
def plot_mesh2d(res, display_bnd=False, display_liq_bnd=False, fig_name=''): """ Plot a 2d triangular mesh with either boundary conditions or liquid boundary number @param input_file (string) File from wich to read the mesh @param bnd_file (string) Name of the boundary file (only used if display_bnd or display_liq_bnd is True) @param display_bnd (boolean) If True display boundary type for each boundary node @param display_liq bnd (boolean) If True display liquidi boundary number for each boundary node @param fig_name (str) If not empty save the plot in that file instead of showing it """ if (display_bnd or display_liq_bnd) and res.boundary_file == '': raise TelemacException(\ "bnd_file is mandatory if using --bnd or --liq-bnd") vnv_plot2d(res.varnames[0], res, plot_mesh=True, annotate_bnd=display_bnd, annotate_liq_bnd=display_liq_bnd, aspect_ratio="equal", fig_name=fig_name)
def get_float_type_from_float(f, endian, nfloat): """ Identifies float precision from the file (single or double) @param f (file descriptor) File descriptor @param endian (string) Endianess type ("<" for little ">" for big) @param nfloat (float) Float to compare to @return (string, integer) Returns the string to be used for readinf ans the number of byte on which the float is encoded ('f', 4) for single ('d',8) for double precision """ pointer = f.tell() ifloat = 4 cfloat = 'f' l = unpack(endian + 'i', f.read(4)) if l[0] != ifloat * nfloat: ifloat = 8 cfloat = 'd' _ = unpack(endian + str(nfloat) + cfloat, f.read(ifloat * nfloat)) chk = unpack(endian + 'i', f.read(4)) if l != chk: raise TelemacException(\ '... Cannot read {} floats from your binary file' ' +> Maybe it is the wrong file format ?' ''.format(str(nfloat))) f.seek(pointer) return cfloat, ifloat
def get_endian_from_char(f, nchar): """ Returns endianess of the file by trying to read a value in the file and comparing it to nchar @param f (file descriptor) File descriptor @param nchar (string) String to compare to @returns (string) String for endianess ("<" for little ">" for big) """ pointer = f.tell() endian = ">" # "<" means little-endian, ">" means big-endian l, _, chk = unpack(endian + 'i' + str(nchar) + 'si', f.read(4 + nchar + 4)) if chk != nchar: endian = "<" f.seek(pointer) l, _, chk = unpack(endian + 'i' + str(nchar) + 'si', f.read(4 + nchar + 4)) if l != chk: raise TelemacException(\ '... Cannot read {} characters from your binary file' ' +> Maybe it is the wrong file format ?' ''.format(str(nchar))) f.seek(pointer) return endian
def subset_variables_slf(vrs, all_vars): """ Take a string in the format "var1:object;var2:object;var3;var4" and returns two list one of index and one of values of all the variables in all_vars that match var. @param vrs (string) String contain ; separated var:object values @param all_vars (list) List of the variables to match with @return (list) list of index of the matching variables @return (list) list of names of the matching variables """ ids = [] names = [] # vrs has the form "var1:object;var2:object;var3;var4" # /!\ the ; separator might be a problem for command line action variable = vrs.replace(',', ';').split(';') for var in variable: var_name = var.split(':')[0] # Loop on variables in file for jvar in range(len(all_vars)): # Filling varname with spaces full_var_name = all_vars[jvar].lower() + \ " "*(16-len(all_vars[jvar])) # if varnme is in the variable name adding it if var_name.lower() in full_var_name: ids.append(jvar) names.append(all_vars[jvar].strip()) if len(ids) < len(variable): raise TelemacException(\ "... Could not find {} in {}" " +> may be you forgot to switch name spaces into " "underscores in your command ?" "".format(variable, str(all_vars))) return ids, names
def generate_get(output_variable): """ Will generate a string containing a call to the get of the api @param output_variable Eficas output_variable rubrique @returns a string """ string = "" # Getting name of python variable name = output_variable['NAME'] # Getting name of the variable in the API var_name = output_variable['VAR_INFO']['VAR_NAME'] # Checking what type of zone definition we have if 'INDEX' in output_variable['VAR_INFO']['ZONE_DEF']: i, j, k = output_variable['VAR_INFO']['ZONE_DEF']['INDEX'] string = "%s = my_case.get('%s', i=%i, j=%i, k=%i)" % (name, var_name, i, j, k) else: raise TelemacException("Missin Zone definition") return string
def extract_timeseries(file_name, var_name, points=None, nodes=None): """ Extract timeseries informations on a list of nodes or points @param file_name (str) Name of the file from which to extract @param var_name (str) Name of the variable to extract @param points (List) List of points on which to extract @param nodes (List) List of nodes on which to extract @returns (List, numpy.array) List of strings (name for each column), the extracted data """ res = TelemacFile(file_name) header = ['time (s)'] if points is not None: tmp_data = res.get_timeseries_on_points(var_name, points) for point in points: header.append(str(point)) elif nodes is not None: tmp_data = res.get_timeseries_on_nodes(var_name, nodes) for node in nodes: header.append(str(node)) else: raise TelemacException("Give at least points or nodes") data = np.vstack((res.times, tmp_data)) res.close() return header, data.T