def get_density_and_time(scname,dstart,dend):
    """
    Get the density measurements from the given spacecraft within the given date range.

    Args:
        scname (str): Spacecraft name (currently 'rbspa' or 'rbspb' are accepted)

        dstart (datetime): Start date

        dend (datetime): End date

    Returns:
        A tuple containing the following arrays:
            - times (array of datetime objects)
            - otimes (array of ordinal times produced by running matplotlib's date2num on the times array)
            - MLT (array of magnetic local time values corresponding to otimes)
            - MLAT (array of magnetic latitudes corresponding to otimes)
            - InvLat (array of invariant latitude corresponding to otimes)
            - density (array of densities corresponding to otimes)
    """
    times,density=emfisis.get_data(scname,['Epoch','density'],dstart,dend)
    #density=emfisis.get_data(scname,'density',dstart,dend)
    ephem=ephemeris.ephemeris(scname,dstart,dend+timedelta(1))
    Lsint=ephem.get_interpolator('Lsimple')
    MLTint=ephem.get_interpolator('EDMAG_MLT')
    MLATint=ephem.get_interpolator('EDMAG_MLAT')
    InvLatint=ephem.get_interpolator('InvLat')
    otimes=date2num(times)
    return times,Lsint(otimes),MLTint(otimes),MLATint(otimes),InvLatint(otimes),density
def navigation(trackResults, settings):
  numGoodSats = 0
  for i in range(len(trackResults)):
    if (trackResults[i].status == 'T'):
      numGoodSats = numGoodSats + 1
  if (numGoodSats < 4):
    raise Exception('Too few satellites to calculate nav solution')
  ##TODO : check lengths of all trackResults prompt correlations?
  if (len(trackResults[0].I_P) < 36000):
    raise Exception('Length of tracking too short to calculate nav solution')

  (subFrameStart, activeChnList) = findPreambles(trackResults,settings)
  
  #Pass 1500 nav bits (5 subframes), starting at a subframe preamble, to ephemeris.py to get ephemeris
  eph = [[] for i in range(32)]
#  for channelNr in activeChnList:
  ##TODO : CHANGE FOR LOOP BACK TO OVER activeChnList##
  for channelNr in [0]:
    #Get 1500 nav bits starting at a subframe
    navBitsIndices = np.r_[subFrameStart[channelNr]:subFrameStart[channelNr]+(1500*20)]
    navBits = corrs2bits.unsigned(trackResults[channelNr].I_P[navBitsIndices])
    #Get the last parity bit of the previous subFrame 
    #subFrame's first 24 bits are XOR'd with it before transmission
    D30starIndices = np.r_[subFrameStart[channelNr]-20:subFrameStart[channelNr]]
    D30star = corrs2bits.unsigned(trackResults[channelNr].I_P[D30starIndices])
    #Extract ephemeris from the 5 subFrames
    (eph[trackResults[channelNr].PRN], TOW) = ephemeris(navBits,D30star)

  ##TODO : remove below statement
  (navSolutions, eph) = (0,0)
  return (navSolutions, eph)
Beispiel #3
0
def obs(bot, update, args):
    obj_name = args[0]
    try:
        day_offset = args[1]
    except:
        day_offset = None
    bot.send_message(chat_id=update.message.chat_id,
                     text=ephemeris.ephemeris(obj_name, day_offset),
                     parse_mode='Markdown')
def poa(beam_horizontal, sky_diffuse_horizontal, zeit_vektor, azimuth_pv, tilt,
        latitude, longitude):
    # Import der Module
    import pvlib
    import numpy as np
    import math
    from timeit import default_timer as timer
    from ephemeris import ephemeris
    import copy
    import pandas as pd
    # Bestimmen der Sonnenpostition
    solpos = ephemeris(zeit_vektor, latitude, longitude)

    # Bestimmen des Einfallswinkels
    theta = pvlib.irradiance.aoi(tilt, azimuth_pv, solpos.zenith,
                                 solpos.azimuth)
    theta_numpy = theta.to_numpy()  # pylint: disable=maybe-no-member

    iam = np.maximum(
        0,
        1 - 0.05 * (1 / np.cos(np.radians(np.minimum(90, theta_numpy))) - 1))
    # Direkte Strahlung auf geneigter Ebene
    i = np.bitwise_and(solpos.elevation <= 2, beam_horizontal > 0)
    beam_horizontal[i] = 0

    elevation_numpy = solpos.elevation.to_numpy()

    g_direkt = iam * beam_horizontal * np.cos(
        np.radians(theta_numpy)) / np.sin(np.radians(elevation_numpy))
    g_direkt[g_direkt < 0] = 0
    # Diffuse Strahlung nach Klucher
    global_irradiance = beam_horizontal + sky_diffuse_horizontal
    g_diffus_pv = pvlib.irradiance.klucher(tilt, azimuth_pv,
                                           sky_diffuse_horizontal,
                                           global_irradiance, solpos.elevation,
                                           solpos.azimuth)
    g_diffus_pv_numpy = g_diffus_pv.to_numpy()
    # Bodenreflexion
    g_reflexion = global_irradiance * 0.1 * (1 - np.cos(np.radians(tilt)))
    # Globalstrahlung PV
    g_global_pv = g_direkt + g_diffus_pv_numpy + g_reflexion
    g_global_pv[g_global_pv < 0] = 0
    return g_global_pv
Beispiel #5
0
def navigation(trackResults, settings):

  numGoodSats = 0
  for i in range(len(trackResults)):
    if (trackResults[i].status == 'T'):
      numGoodSats = numGoodSats + 1
  if (numGoodSats < 4):
    raise Exception('Too few satellites to calculate nav solution')
  #TODO : check lengths of all trackResults prompt correlations?
  if (len(trackResults[0].I_P) < 36000):
    raise Exception('Length of tracking too short to calculate nav solution')

  (subFrameStart, activeChnList) = findPreambles(trackResults,settings)

  #Pass 1500 nav bits (5 subframes), starting at a subframe preamble, 
  #to ephemeris.py to get ephemeris
  eph = [[] for i in range(32)]
  for channelNr in reversed(activeChnList):
    #Get 1500 nav bits starting at a subframe
    navBitsIndices = np.r_[subFrameStart[channelNr]:subFrameStart[channelNr]+(1500*20)]
    navBits = corrs2bits.unsigned(trackResults[channelNr].I_P[navBitsIndices])
    #Get the last parity bit of the previous subFrame 
    #subFrame's first 24 bits are XOR'd with it before transmission
    D30starIndices = np.r_[subFrameStart[channelNr]-20:subFrameStart[channelNr]]
    D30star = corrs2bits.unsigned(trackResults[channelNr].I_P[D30starIndices])
    #Extract ephemeris from the 5 subFrames
    (eph[trackResults[channelNr].PRN], TOW) = ephemeris(navBits,D30star)
    #TODO : Implement better way to determine if satellite is usable (health, accuracy)
    #Exclude satellite if for some reason ephemeris parameters weren't assigned
    #(subframe ID's 1-3 weren't assigned?)
    if (eph[trackResults[channelNr].PRN].IODC==0 and 
          eph[trackResults[channelNr].PRN].IODC_sf2==0 and 
            eph[trackResults[channelNr].PRN].IODC_sf3==0):
      activeChnList.pop(channelNr)
  #If we don't have enough satellites after rejecting those whose ephemerides failed
  #to extract properly, then we can't calculate the nav solution
  if len(activeChnList) < 4:
    raise Exception('Not enough satellites after extracting ephemerides to calculate nav solution')
  #TODO : include support for an initial position here and associated elevation mask
  #Include all satellites for first iteration of the nav solution
  satElev = np.ones(len(activeChnList))*90

  readyChnList = activeChnList[:]

  transmitTime = TOW

  msToProcessNavigation = np.int(np.floor((settings.msToProcess-max(subFrameStart))/settings.navSolPeriod))
  navSolutions = navSolutions_class(msToProcessNavigation)

  for currMeasNr in range(1):
#  for currMeasNr in range(msToProcessNavigation):
    if currMeasNr == 0: #append indexes to arrays that need them appended
      for i in range(len(activeChnList)):
        navSolutions.channel.rawP[]
    activeChnList = gThanMask(satElev)
    for i in activeChnList:
      navSolutions.channel.PRN[i].append(trackResults[i].PRN)
    navSolutions.channel.el[currMeasNr] = [[] for i in range(len(activeChnList))]
    navSolutions.channel.az[currMeasNr] = [[] for i in range(len(activeChnList))]

    #Find pseudoranges
    for channelNumber in activeChnList:
      navSolutions.channel.rawP[channelNumber][currMeasNr] = calculatePseudorange(trackResults, \
                                      [i + settings.navSolPeriod * (currMeasNr) for i in subFrameStart], \
                                      channelNumber, \
                                      settings)

    #Find satellite positions and clock corrections
    (satPositions, satClkCorr) = satpos(transmitTime, \
                                        [trackResults[i].PRN for i in activeChnList], \
                                        eph, \
                                        settings)

    #Find receiver position
    #We can only calculate solution if >= 4 satellites are found
    if len(activeChnList) > 3:
      #Calculate receiver position
      (xyzdt, \
        navSolutions.channel.el, \
        navSolutions.channel.az, \
        navSolutions.DOP[currMeasNr]) = leastSquarePos(satPositions, navSolutions.channel.rawP[np.r_[activeChnList]][currMeasNr] + satClkCorr*settings.c, settings)
      
      

  #TODO : remove below statement
  (navSolutions, eph) = (0,0)
  return (navSolutions, eph)
    def postNavigate(self):
        trackResults = self._results
        settings = self._settings
        # Function calculates navigation solutions for the receiver (pseudoranges,
        # positions). At the end it converts coordinates from the WGS84 system to
        # the UTM, geocentric or any additional coordinate system.

        # [navSolutions, eph] = postNavigation(trackResults, settings)

        #   Inputs:
        #       trackResults    - results from the tracking function (structure
        #                       array).
        #       settings        - receiver settings.
        #   Outputs:
        #       navSolutions    - contains measured pseudoranges, receiver
        #                       clock error, receiver coordinates in several
        #                       coordinate systems (at least ECEF and UTM).
        #       eph             - received ephemerides of all SV (structure array).

        # Check is there enough data to obtain any navigation solution ===========
        # It is necessary to have at least three subframes (number 1, 2 and 3) to
        # find satellite coordinates. Then receiver position can be found too.
        # The function requires all 5 subframes, because the tracking starts at
        # arbitrary point. Therefore the first received subframes can be any three
        # from the 5.
        # One subframe length is 6 seconds, therefore we need at least 30 sec long
        # record (5 * 6 = 30 sec = 30000ms). We add extra seconds for the cases,
        # when tracking has started in a middle of a subframe.

        if settings.msToProcess < 36000 or sum(trackResults.status != '-') < 4:
            # Show the error message and exit
            print 'Record is to short or too few satellites tracked. Exiting!'
            navSolutions = None
            self._solutions = navSolutions
            eph = None
            self._eph = eph
            return

        # Find preamble start positions ==========================================

        subFrameStart, activeChnList = self.findPreambles()

        # Decode ephemerides =====================================================
        field_str = 'weekNumber,accuracy,health,T_GD,IODC,t_oc,a_f2,a_f1,a_f0,'
        field_str += 'IODE_sf2,C_rs,deltan,M_0,C_uc,e,C_us,sqrtA,t_oe,'
        field_str += 'C_ic,omega_0,C_is,i_0,C_rc,omega,omegaDot,IODE_sf3,iDot'
        eph = np.recarray((32,), formats=['O'] * 27, names=field_str)
        for channelNr in activeChnList:
            # === Convert tracking output to navigation bits =======================
            # --- Copy 5 sub-frames long record from tracking output ---------------
            navBitsSamples = trackResults[channelNr].I_P[subFrameStart[channelNr] - 20:
                                                         subFrameStart[channelNr] + 1500 * 20].copy()

            navBitsSamples = navBitsSamples.reshape(20, -1, order='F')

            navBits = navBitsSamples.sum(0)

            # The expression (navBits > 0) returns an array with elements set to 1
            # if the condition is met and set to 0 if it is not met.
            navBits = (navBits > 0) * 1

            # The function ephemeris expects input in binary form. In Matlab it is
            # a string array containing only "0" and "1" characters.
            navBitsBin = map(str, navBits)

            eph[trackResults[channelNr].PRN - 1], TOW = ephemeris.ephemeris(navBitsBin[1:], navBitsBin[0])

            if eph[trackResults[channelNr].PRN - 1].IODC is None or \
                    eph[trackResults[channelNr].PRN - 1].IODE_sf2 is None or \
                    eph[trackResults[channelNr].PRN - 1].IODE_sf3 is None:
                # --- Exclude channel from the list (from further processing) ------
                activeChnList = np.setdiff1d(activeChnList, channelNr)

        # Check if the number of satellites is still above 3 =====================
        if activeChnList.size == 0 or activeChnList.size < 4:
            # Show error message and exit
            print 'Too few satellites with ephemeris data for position calculations. Exiting!'
            navSolutions = None
            self._solutions = navSolutions
            eph = None
            self._eph = eph
            return

        # Initialization =========================================================

        # Set the satellite elevations array to INF to include all satellites for
        # the first calculation of receiver position. There is no reference point
        # to find the elevation angle as there is no receiver position estimate at
        # this point.
        satElev = np.Inf * np.ones(settings.numberOfChannels)

        # Save the active channel list. The list contains satellites that are
        # tracked and have the required ephemeris data. In the next step the list
        # will depend on each satellite's elevation angle, which will change over
        # time.
        readyChnList = activeChnList.copy()

        transmitTime = TOW

        ###########################################################################
        #   Do the satellite and receiver position calculations                  #
        ###########################################################################
        # Initialization of current measurement ==================================
        channel = np.rec.array([(np.zeros((settings.numberOfChannels, 64)),
                                 np.nan * np.ones((settings.numberOfChannels, 64)),
                                 np.nan * np.ones((settings.numberOfChannels, 64)),
                                 np.nan * np.ones((settings.numberOfChannels, 64)),
                                 np.nan * np.ones((settings.numberOfChannels, 64))
                                 )], formats=['O'] * 5, names='PRN,el,az,rawP,correctedP')
        navSolutions = np.rec.array([(channel,
                                      np.zeros((5, 64)),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      0,
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64),
                                      np.nan * np.ones(64)
                                      )], formats=['O'] * 13,
                                    names='channel,DOP,X,Y,Z,dt,latitude,longitude,height,utmZone,E,N,U')
        for currMeasNr in range(np.int(np.fix(settings.msToProcess - subFrameStart.max()) / settings.navSolPeriod)):
            # Exclude satellites, that are below elevation mask
            activeChnList = np.intersect1d((satElev >= settings.elevationMask).nonzero()[0], readyChnList)

            channel[0].PRN[activeChnList, currMeasNr] = trackResults[activeChnList].PRN

            # do to elevation mask will not "jump" to position (0,0) in the sky
            # plot.
            # channel[0].el[:, currMeasNr] = np.nan * np.ones(settings.numberOfChannels)

            # channel[0].az[:, currMeasNr] = np.nan * np.ones(settings.numberOfChannels)

            # Find pseudoranges ======================================================
            channel[0].rawP[:, currMeasNr] = self.calculatePseudoranges(
                subFrameStart + settings.navSolPeriod * currMeasNr,
                activeChnList)

            # Find satellites positions and clocks corrections =======================
            satPositions, satClkCorr = satpos(transmitTime, trackResults[activeChnList].PRN, eph, settings)

            # Find receiver position =================================================
            # 3D receiver position can be found only if signals from more than 3
            # satellites are available
            if activeChnList.size > 3:
                # === Calculate receiver position ==================================
                (xyzdt,
                 channel[0].el[activeChnList, currMeasNr],
                 channel[0].az[activeChnList, currMeasNr],
                 navSolutions[0].DOP[:, currMeasNr]) = leastSquarePos(satPositions,
                                                                      channel[0].rawP[
                                                                          activeChnList, currMeasNr] +
                                                                      satClkCorr * settings.c,
                                                                      settings)

                navSolutions[0].X[currMeasNr] = xyzdt[0]

                navSolutions[0].Y[currMeasNr] = xyzdt[1]

                navSolutions[0].Z[currMeasNr] = xyzdt[2]

                navSolutions[0].dt[currMeasNr] = xyzdt[3]

                satElev = channel[0].el[:, currMeasNr]

                channel[0].correctedP[activeChnList, currMeasNr] = channel[0].rawP[activeChnList, currMeasNr] + \
                                                                   satClkCorr * settings.c + \
                                                                   navSolutions[0].dt[currMeasNr]

                # Coordinate conversion ==================================================
                # === Convert to geodetic coordinates ==============================
                (navSolutions[0].latitude[currMeasNr],
                 navSolutions[0].longitude[currMeasNr],
                 navSolutions[0].height[currMeasNr]) = cart2geo(navSolutions[0].X[currMeasNr],
                                                                navSolutions[0].Y[currMeasNr],
                                                                navSolutions[0].Z[currMeasNr],
                                                                4)

                navSolutions[0].utmZone = findUtmZone(navSolutions[0].latitude[currMeasNr],
                                                      navSolutions[0].longitude[currMeasNr])

                (navSolutions[0].E[currMeasNr],
                 navSolutions[0].N[currMeasNr],
                 navSolutions[0].U[currMeasNr]) = cart2utm(xyzdt[0], xyzdt[1], xyzdt[2],
                                                           navSolutions[0].utmZone)

            else:
                # --- There are not enough satellites to find 3D position ----------
                print '   Measurement No. %d' % currMeasNr + ': Not enough information for position solution.'
                # excluded automatically in all plots. For DOP it is easier to use
                # zeros. NaN values might need to be excluded from results in some
                # of further processing to obtain correct results.
                navSolutions[0].X[currMeasNr] = np.nan

                navSolutions[0].Y[currMeasNr] = np.nan

                navSolutions[0].Z[currMeasNr] = np.nan

                navSolutions[0].dt[currMeasNr] = np.nan

                navSolutions[0].DOP[:, currMeasNr] = np.zeros(5)

                navSolutions[0].latitude[currMeasNr] = np.nan

                navSolutions[0].longitude[currMeasNr] = np.nan

                navSolutions[0].height[currMeasNr] = np.nan

                navSolutions[0].E[currMeasNr] = np.nan

                navSolutions[0].N[currMeasNr] = np.nan

                navSolutions[0].U[currMeasNr] = np.nan

                channel[0].az[activeChnList, currMeasNr] = np.nan * np.ones(activeChnList.shape)

                channel[0].el[activeChnList, currMeasNr] = np.nan * np.ones(activeChnList.shape)

            # satellites are excluded do to elevation mask. Therefore raising
            # satellites will be not included even if they will be above
            # elevation mask at some point. This would be a good place to
            # update positions of the excluded satellites.
            # === Update the transmit time ("measurement time") ====================
            transmitTime += settings.navSolPeriod / 1000

        self._solutions = navSolutions
        self._eph = eph
        return