Example #1
0
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
Example #2
0
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
Example #3
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
Example #4
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
Example #5
0
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