def read(fin: TextIO, alphabet: Alphabet = None) -> SeqList: """Read a sequence file and attempt to guess its format. First the filename extension (if available) is used to infer the format. If that fails, then we attempt to parse the file using several common formats. Note, fin cannot be unseekable stream such as sys.stdin returns : SeqList Raises : ValueError: If the file cannot be parsed. ValueError: Sequence do not conform to the alphabet. """ alphabet = Alphabet(alphabet) parsers = _get_parsers(fin) for p in parsers: fin.seek(0) try: return p.read(fin, alphabet) except ValueError: pass names = ", ".join([p.names[0] for p in parsers]) raise ValueError("Cannot parse sequence file: Tried %s " % names)
def reversed_blocks(f: TextIO, blocksize=4096): """ Generate blocks of file's contents in reverse order. """ f.seek(0, os.SEEK_END) here = f.tell() while 0 < here: delta = min(blocksize, here) here -= delta f.seek(here, os.SEEK_SET) yield f.read(delta)
def navheader3(f: TextIO) -> Dict[str, Any]: if isinstance(f, Path): fn = f with fn.open('r') as f: return navheader3(f) else: f.seek(0) hdr = rinexinfo(f) assert int(hdr['version']) == 3, 'see rinexnav2() for RINEX 2.x files' assert hdr['filetype'] == 'N', 'Did not detect Nav file' for ln in f: if 'END OF HEADER' in ln: break kind, content = ln[60:].strip(), ln[:60] if kind == "IONOSPHERIC CORR": if kind not in hdr: hdr[kind] = {} coefficients_kind = content[:4].strip() if coefficients_kind == 'GAL': n_corr = 3 else: n_corr = 4 coefficients = [ rinex_string_to_float(content[5 + i * 12:5 + (i + 1) * 12]) for i in range(n_corr) ] hdr[kind][coefficients_kind] = coefficients elif kind == "LEAP SECONDS": hdr[kind] = content.split()[0] else: hdr[kind] = content return hdr
def obsheader2(f: TextIO, useindicators: bool = False, meas: Sequence[str] = None) -> Dict[str, Any]: """ End users should use rinexheader() """ if isinstance(f, (str, Path)): with opener(f, header=True) as h: return obsheader2(h, useindicators, meas) f.seek(0) # %% selection if isinstance(meas, str): meas = [meas] if not meas or not meas[0].strip(): meas = None hdr = rinexinfo(f) Nobs = 0 # not None due to type checking for ln in f: if "END OF HEADER" in ln: break h = ln[60:80].strip() c = ln[:60] # %% measurement types if '# / TYPES OF OBSERV' in h: if Nobs == 0: Nobs = int(c[:6]) hdr[h] = c[6:].split() else: hdr[h] += c[6:].split() elif h not in hdr: # Header label hdr[h] = c # string with info else: # concatenate hdr[h] += " " + c # %% useful values try: hdr['systems'] = hdr['RINEX VERSION / TYPE'][40] except KeyError: pass hdr['Nobs'] = Nobs # 5 observations per line (incorporating LLI, SSI) hdr['Nl_sv'] = ceil(hdr['Nobs'] / 5) # %% list with receiver location in x,y,z cartesian ECEF (OPTIONAL) try: hdr['position'] = [float(j) for j in hdr['APPROX POSITION XYZ'].split()] if ecef2geodetic is not None: hdr['position_geodetic'] = ecef2geodetic(*hdr['position']) except (KeyError, ValueError): pass # %% observation types try: hdr['fields'] = hdr['# / TYPES OF OBSERV'] if Nobs != len(hdr['fields']): raise ValueError(f'{f.name} header read incorrectly') if isinstance(meas, (tuple, list, np.ndarray)): ind = np.zeros(len(hdr['fields']), dtype=bool) for m in meas: for i, f in enumerate(hdr['fields']): if f.startswith(m): ind[i] = True hdr['fields_ind'] = np.nonzero(ind)[0] else: ind = slice(None) hdr['fields_ind'] = np.arange(Nobs) hdr['fields'] = np.array(hdr['fields'])[ind].tolist() except KeyError: pass hdr['Nobsused'] = hdr['Nobs'] if useindicators: hdr['Nobsused'] *= 3 # %% try: hdr['# OF SATELLITES'] = int(hdr['# OF SATELLITES'][:6]) except (KeyError, ValueError): pass # %% time try: hdr['t0'] = _timehdr(hdr['TIME OF FIRST OBS']) except (KeyError, ValueError): pass try: hdr['t1'] = _timehdr(hdr['TIME OF LAST OBS']) except (KeyError, ValueError): pass try: # This key is OPTIONAL hdr['interval'] = float(hdr['INTERVAL'][:10]) except (KeyError, ValueError): pass return hdr
def obsheader2(f: TextIO, useindicators: bool = False, meas: Sequence[str] = None) -> Dict[str, Any]: """ End users should use rinexheader() """ if isinstance(f, (str, Path)): with opener(f, header=True) as h: return obsheader2(h, useindicators, meas) f.seek(0) # %% selection if isinstance(meas, str): meas = [meas] if not meas or not meas[0].strip(): meas = None hdr = rinexinfo(f) Nobs = 0 # not None due to type checking for ln in f: if "END OF HEADER" in ln: break h = ln[60:80].strip() c = ln[:60] # %% measurement types if "# / TYPES OF OBSERV" in h: if Nobs == 0: Nobs = int(c[:6]) hdr[h] = c[6:].split() else: hdr[h] += c[6:].split() elif h not in hdr: # Header label hdr[h] = c # string with info else: # concatenate hdr[h] += " " + c # %% useful values try: hdr["systems"] = hdr["RINEX VERSION / TYPE"][40] except KeyError: pass hdr["Nobs"] = Nobs # 5 observations per line (incorporating LLI, SSI) hdr["Nl_sv"] = ceil(hdr["Nobs"] / 5) # %% list with receiver location in x,y,z cartesian ECEF (OPTIONAL) try: hdr["position"] = [ float(j) for j in hdr["APPROX POSITION XYZ"].split() ] if ecef2geodetic is not None: hdr["position_geodetic"] = ecef2geodetic(*hdr["position"]) except (KeyError, ValueError): pass # %% observation types try: hdr["fields"] = hdr["# / TYPES OF OBSERV"] if hdr["Nobs"] != len(hdr["fields"]): logging.error( f"{f.name} number of observations declared in header does not match fields" ) hdr["Nobs"] = len(hdr["fields"]) if isinstance(meas, (tuple, list, np.ndarray)): ind = np.zeros(len(hdr["fields"]), dtype=bool) for m in meas: for i, f in enumerate(hdr["fields"]): if f.startswith(m): ind[i] = True hdr["fields_ind"] = np.nonzero(ind)[0] else: ind = np.s_[:] hdr["fields_ind"] = np.arange(hdr["Nobs"]) hdr["fields"] = np.array(hdr["fields"])[ind].tolist() except KeyError: pass hdr["Nobsused"] = hdr["Nobs"] if useindicators: hdr["Nobsused"] *= 3 # %% try: hdr["# OF SATELLITES"] = int(hdr["# OF SATELLITES"][:6]) except (KeyError, ValueError): pass # %% time try: hdr["t0"] = _timehdr(hdr["TIME OF FIRST OBS"]) except (KeyError, ValueError): pass try: hdr["t1"] = _timehdr(hdr["TIME OF LAST OBS"]) except (KeyError, ValueError): pass try: # This key is OPTIONAL hdr["interval"] = float(hdr["INTERVAL"][:10]) except (KeyError, ValueError): pass try: s = " " hdr["rxmodel"] = s.join(hdr["REC # / TYPE / VERS"].split()[1:-1]) except (KeyError, ValueError): pass return hdr
def set_pos_after_license(file: TextIO) -> None: for line in file: if re.search(r"SPDX-License-Identifier", line): return file.seek(0, 0) return