def _skip(f: TextIO, ln: str, Nl_sv: int, sv: Sequence[str] = None): """ skip ahead to next time step """ if sv is None: sv = _getsvind(f, ln) # f.seek(len(sv)*Nl_sv*80, 1) # not for io.TextIOWrapper ? for _ in range(len(sv) * Nl_sv): f.readline()
def _skip(f: TextIO, ln: str, Nl_sv: int, sv: Sequence[str] = None): """ skip ahead to next time step """ if sv is None: sv = _getsvind(f, ln) # f.seek(len(sv)*Nl_sv*80, 1) # not for io.TextIOWrapper ? for _ in range(len(sv)*Nl_sv): f.readline()
def read_text_record(stream: TextIO) -> Optional[MarcRecord]: """ Чтение записи из файла в текстовом обменном формате ИРБИС. :param stream: Файл :return: Запись или None """ result = MarcRecord() while True: line: str = stream.readline() if not line: break line = line.strip() if line.startswith(STOP_MARKER): break if not line.startswith('#'): break parts = line[1:].split(':', 1) if len(parts) != 2: break tag = int(parts[0]) text = parts[1][1:] field = RecordField(tag) field.parse(text) result.fields.append(field) if not result.fields: # Если в записи нет полей, возвращаем None return None return result
def _getObsTypes(f: TextIO, use: Union[str, list, tuple]) -> Tuple[Dict, Dict, int]: """ get RINEX 3 OBS types, for each system type""" header: Dict[str, Any] = {} fields = {} Fmax = 0 # Capture header info for ln in f: if "END OF HEADER" in ln: break h = ln[60:80] c = ln[:60] if 'SYS / # / OBS TYPES' in h: k = c[0] fields[k] = c[6:60].split() N = int(c[3:6]) Fmax = max(N, Fmax) n = N - 13 while n > 0: # Rinex 3.03, pg. A6, A7 ln = f.readline() assert 'SYS / # / OBS TYPES' in ln[60:] fields[k] += ln[6:60].split() n -= 13 assert len(fields[k]) == N continue if h.strip() not in header: # Header label header[h.strip()] = c # don't strip for fixed-width parsers # string with info else: # concatenate to the existing string header[h.strip()] += " " + c # %% sanity check for Mandatory RINEX 3 headers for h in ('APPROX POSITION XYZ', ): if h not in header: raise OSError( 'Mandatory RINEX 3 headers are missing from file, is it a valid RINEX 3 file?' ) # list with x,y,z cartesian header['APPROX POSITION XYZ'] = [ float(j) for j in header['APPROX POSITION XYZ'].split() ] # %% select specific satellite systems only (optional) if use is not None: fields = {k: fields[k] for k in use} return fields, header, Fmax
def _getsvind(f: TextIO, ln: str) -> List[str]: Nsv = int(ln[29:32]) # Number of visible satellites this time %i3 # get first 12 SV ID's sv = _getSVlist(ln, min(12, Nsv), []) # any more SVs? n = Nsv - 12 while n > 0: sv = _getSVlist(f.readline(), min(12, n), sv) n -= 12 if Nsv != len(sv): raise LookupError('satellite list read incorrectly') return sv
def _getObsTypes(f: TextIO, use: Union[str, list, tuple]) -> tuple: """ get RINEX 3 OBS types, for each system type""" header = {} fields = {} Fmax = 0 # Capture header info for l in f: if "END OF HEADER" in l: break h = l[60:80] c = l[:60] if 'SYS / # / OBS TYPES' in h: k = c[0] fields[k] = c[6:60].split() N = int(c[3:6]) Fmax = max(N, Fmax) n = N - 13 while n > 0: # Rinex 3.03, pg. A6, A7 l = f.readline() assert 'SYS / # / OBS TYPES' in l[60:] fields[k] += l[6:60].split() n -= 13 assert len(fields[k]) == N continue if h.strip() not in header: #Header label header[h.strip()] = c # don't strip for fixed-width parsers # string with info else: # concatenate to the existing string header[h.strip()] += " " + c # list with x,y,z cartesian header['APPROX POSITION XYZ'] = [ float(j) for j in header['APPROX POSITION XYZ'].split() ] # %% select specific satellite systems only (optional) if isinstance(use, str): fields = fields[use] elif isinstance(use, (tuple, list, np.ndarray)): fields = [fields[u] for u in use] return fields, header, Fmax
def _getsvind(f: TextIO, ln: str) -> List[str]: if len(ln) < 32: raise ValueError(f"satellite index line truncated: {ln}") Nsv = int(ln[29:32]) # Number of visible satellites this time %i3 # get first 12 SV ID's sv = _getSVlist(ln, min(12, Nsv), []) # any more SVs? n = Nsv - 12 while n > 0: sv = _getSVlist(f.readline(), min(12, n), sv) n -= 12 if Nsv != len(sv): raise ValueError("satellite list read incorrectly") return sv
def _getsvind(f: TextIO, ln: str) -> List[str]: if len(ln) < 32: raise ValueError(f'satellite index line truncated: {ln}') Nsv = int(ln[29:32]) # Number of visible satellites this time %i3 # get first 12 SV ID's sv = _getSVlist(ln, min(12, Nsv), []) # any more SVs? n = Nsv-12 while n > 0: sv = _getSVlist(f.readline(), min(12, n), sv) n -= 12 if Nsv != len(sv): raise ValueError('satellite list read incorrectly') return sv
def first_nonblank_line(f: TextIO, max_lines: int = 10) -> str: """ return first non-blank 80 character line in file Parameters ---------- max_lines: int maximum number of blank lines """ line = "" for _i in range(max_lines): line = f.readline(81) if line.strip(): break if _i == max_lines - 1 or not line: raise ValueError(f"could not find first valid header line in {f.name}") return line
def obsheader3(f: TextIO, use: Sequence[str] = None, meas: Sequence[str] = None) -> Dict[str, Any]: """ get RINEX 3 OBS types, for each system type optionally, select system type and/or measurement type to greatly speed reading and save memory (RAM, disk) """ if isinstance(f, (str, Path)): with opener(f, header=True) as h: return obsheader3(h, use, meas) fields = {} Fmax = 0 # %% first line hdr = rinexinfo(f) for ln in f: if "END OF HEADER" in ln: break h = ln[60:80] c = ln[:60] if 'SYS / # / OBS TYPES' in h: k = c[0] fields[k] = c[6:60].split() N = int(c[3:6]) # %% maximum number of fields in a file, to allow fast Numpy parse. Fmax = max(N, Fmax) n = N - 13 while n > 0: # Rinex 3.03, pg. A6, A7 ln = f.readline() assert 'SYS / # / OBS TYPES' in ln[60:] fields[k] += ln[6:60].split() n -= 13 assert len(fields[k]) == N continue if h.strip() not in hdr: # Header label hdr[h.strip()] = c # don't strip for fixed-width parsers # string with info else: # concatenate to the existing string hdr[h.strip()] += " " + c # %% list with x,y,z cartesian (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 # %% time try: t0s = hdr['TIME OF FIRST OBS'] # NOTE: must do second=int(float()) due to non-conforming files hdr['t0'] = datetime(year=int(t0s[:6]), month=int(t0s[6:12]), day=int(t0s[12:18]), hour=int(t0s[18:24]), minute=int(t0s[24:30]), second=int(float(t0s[30:36])), microsecond=int(float(t0s[30:43]) % 1 * 1000000)) except (KeyError, ValueError): pass try: hdr['interval'] = float(hdr['INTERVAL'][:10]) except (KeyError, ValueError): pass # %% select specific satellite systems only (optional) if use is not None: if not set(fields.keys()).intersection(use): raise KeyError(f'system type {use} not found in RINEX file') fields = {k: fields[k] for k in use if k in fields} # perhaps this could be done more efficiently, but it's probably low impact on overall program. # simple set and frozenset operations do NOT preserve order, which would completely mess up reading! sysind = {} if isinstance(meas, (tuple, list, np.ndarray)): for sk in fields: # iterate over each system # ind = np.isin(fields[sk], meas) # boolean vector ind = np.zeros(len(fields[sk]), dtype=bool) for m in meas: for i, f in enumerate(fields[sk]): if f.startswith(m): ind[i] = True fields[sk] = np.array(fields[sk])[ind].tolist() sysind[sk] = np.empty(Fmax * 3, dtype=bool) # *3 due to LLI, SSI for j, i in enumerate(ind): sysind[sk][j * 3:j * 3 + 3] = i else: sysind = {k: slice(None) for k in fields} hdr['fields'] = fields hdr['fields_ind'] = sysind hdr['Fmax'] = Fmax return hdr
def obsheader3(f: TextIO, use: Sequence[str] = None, meas: Sequence[str] = None) -> Dict[str, Any]: """ get RINEX 3 OBS types, for each system type optionally, select system type and/or measurement type to greatly speed reading and save memory (RAM, disk) """ if isinstance(f, (str, Path)): with opener(f, header=True) as h: return obsheader3(h, use, meas) fields = {} Fmax = 0 # %% first line hdr = rinexinfo(f) for ln in f: if "END OF HEADER" in ln: break h = ln[60:80] c = ln[:60] if 'SYS / # / OBS TYPES' in h: k = c[0] fields[k] = c[6:60].split() N = int(c[3:6]) # %% maximum number of fields in a file, to allow fast Numpy parse. Fmax = max(N, Fmax) n = N-13 while n > 0: # Rinex 3.03, pg. A6, A7 ln = f.readline() assert 'SYS / # / OBS TYPES' in ln[60:] fields[k] += ln[6:60].split() n -= 13 assert len(fields[k]) == N continue if h.strip() not in hdr: # Header label hdr[h.strip()] = c # don't strip for fixed-width parsers # string with info else: # concatenate to the existing string hdr[h.strip()] += " " + c # %% list with x,y,z cartesian (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 # %% time try: t0s = hdr['TIME OF FIRST OBS'] # NOTE: must do second=int(float()) due to non-conforming files hdr['t0'] = datetime(year=int(t0s[:6]), month=int(t0s[6:12]), day=int(t0s[12:18]), hour=int(t0s[18:24]), minute=int(t0s[24:30]), second=int(float(t0s[30:36])), microsecond=int(float(t0s[30:43]) % 1 * 1000000)) except (KeyError, ValueError): pass try: hdr['interval'] = float(hdr['INTERVAL'][:10]) except (KeyError, ValueError): pass # %% select specific satellite systems only (optional) if use is not None: if not set(fields.keys()).intersection(use): raise KeyError(f'system type {use} not found in RINEX file') fields = {k: fields[k] for k in use if k in fields} # perhaps this could be done more efficiently, but it's probably low impact on overall program. # simple set and frozenset operations do NOT preserve order, which would completely mess up reading! sysind = {} if isinstance(meas, (tuple, list, np.ndarray)): for sk in fields: # iterate over each system # ind = np.isin(fields[sk], meas) # boolean vector ind = np.zeros(len(fields[sk]), dtype=bool) for m in meas: for i, f in enumerate(fields[sk]): if f.startswith(m): ind[i] = True fields[sk] = np.array(fields[sk])[ind].tolist() sysind[sk] = np.empty(Fmax*3, dtype=bool) # *3 due to LLI, SSI for j, i in enumerate(ind): sysind[sk][j*3:j*3+3] = i else: sysind = {k: slice(None) for k in fields} hdr['fields'] = fields hdr['fields_ind'] = sysind hdr['Fmax'] = Fmax return hdr