Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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