Beispiel #1
0
def invert_example(axes=[], show=True):
    """Test case for reverse engineering rough solar wind params

    We look here at the 1989 storm as studied by Nagatsuma (2015)
    and Boteler (2019)
    """
    import datetime as dt
    import spacepy.toolbox as tb
    # fetch doesn't respect the days (it grabs 1 month at a time)
    # but we'll give the days we're interested in for reference
    st_tup = (1989, 3, 12)
    en_tup = (1989, 3, 15)
    ky_dat = kyo.fetch('dst', st_tup, en_tup)
    st = dt.datetime(*st_tup)
    en = dt.datetime(*en_tup)
    inds = tb.tOverlapHalf([st, en], ky_dat['time'])
    vbz = inverseBurton(ky_dat['dst'][inds], rectify=True)
    vbz_OB = inverseOBrienMcPherron(ky_dat['dst'][inds])

    if not axes:
        fig, ax = plt.subplots(2, sharex=True, figsize=(10, 4.5))
    else:
        ax = axes
    ax[0].plot(ky_dat['time'][inds], vbz / 1e3, 'r-', label='Burton')
    ax[0].set_ylabel('v.B$_{south}$ [mV/m]')
    ax[0].plot(ky_dat['time'][inds], vbz_OB / 1e3, 'b-', label='O-M')
    ax[0].set_ylabel('v.B$_{south}$ [mV/m]')
    ax[0].legend()
    ax[1].plot(ky_dat['time'][inds], ky_dat['dst'][inds])
    ax[1].set_ylabel('Dst [nT]')
    ax[1].set_xlabel('1989')
    if show:
        plt.show()
Beispiel #2
0
def applyRefractory(process1, period):
    '''Apply a refractory period to an input discrete event time sequence

    All events in the refractory period are removed from the point process.

    Parameters
    ==========
    process1 : iterable
        an iterable of datetimes, or a spacepy.time.Ticktock
    period : datetime.timedelta
        length of refractory period

    Returns
    =======
    keep : iterable
        returns pruned set of datetimes with same type as input
        NOTE: array subclasses will be lost
    '''
    import spacepy.time as spt
    if isinstance(process1, spt.Ticktock):
        #SpacePy Ticktock
        p1 = dm.dmcopy(process1.UTC).tolist()
        tickt = True
    elif isinstance(process1[0], dt.datetime):
        #iterable containing datetimes
        p1 = dm.dmcopy(process1)
        try:
            p1 = p1.tolist()
            wasArr = True
        except:
            wasArr = False
        tickt = False
    else:
        raise NotImplementedError(
            'Input process must be a list/array of datetimes, or a spacepy.time.Ticktock'
        )

    try:
        assert period.seconds
    except AssertionError:
        raise AttributeError('period must be a datetime.timedelta')

    done = len(p1) < 2
    keep, discard = [], []
    while not done:
        t1 = p1[0]
        t2 = t1 + period
        inds = tb.tOverlapHalf([t1, t2], p1[1:])
        for idx in inds:
            discard.append(p1.pop(idx + 1))
        keep.append(p1.pop(0))  # put test element into keep array
        done = len(p1) < 2

    if tickt:
        return spt.Ticktock(keep)
    else:
        if wasArr:
            return np.array(keep)
        else:
            return keep
Beispiel #3
0
def applyRefractory(process1, period):
    '''Apply a refractory period to an input discrete event time sequence

    All events in the refractory period are removed from the point process.

    Parameters
    ==========
    process1 : iterable
        an iterable of datetimes, or a spacepy.time.Ticktock
    period : datetime.timedelta
        length of refractory period

    Returns
    =======
    keep : iterable
        returns pruned set of datetimes with same type as input
        NOTE: array subclasses will be lost
    '''
    import spacepy.time as spt
    if isinstance(process1, spt.Ticktock):
        #SpacePy Ticktock
        p1 = dm.dmcopy(process1.UTC).tolist()
        tickt = True
    elif isinstance(process1[0], dt.datetime):
        #iterable containing datetimes
        p1 = dm.dmcopy(process1)
        try:
            p1 = p1.tolist()
            wasArr = True
        except:
            wasArr = False
        tickt = False
    else:
        raise NotImplementedError('Input process must be a list/array of datetimes, or a spacepy.time.Ticktock')

    try:
        assert period.seconds
    except AssertionError:
        raise AttributeError('period must be a datetime.timedelta')

    done = len(p1)<2
    keep, discard = [], []
    while not done:
        t1 = p1[0]
        t2 = t1 + period
        inds = tb.tOverlapHalf([t1, t2], p1[1:])
        for idx in inds:
            discard.append(p1.pop(idx+1))
        keep.append(p1.pop(0)) # put test element into keep array
        done = len(p1)<2

    if tickt:
        return spt.Ticktock(keep)
    else:
        if wasArr:
            return np.array(keep)
        else:
            return keep
Beispiel #4
0
 def test_tOverlapHalf_random(self):
     """Shuffle input before calling tOverlapHalf"""
     real_ans = [1, 2, 6, 7, 10, 12, 13, 14, 15, 17, 18,
                  19, 24, 27, 28, 30, 32, 35, 37, 38]
     random.seed(0)
     #Cut down the python3 rng to the same precision as python2
     random.shuffle(self.dt_a, lambda:round(random.random(), 9))
     random.shuffle(self.dt_b, lambda:round(random.random(), 9))
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b)
     self.assertEqual(real_ans, ans)
Beispiel #5
0
 def test_tOverlapHalf_random(self):
     """Shuffle input before calling tOverlapHalf"""
     real_ans = [1, 2, 6, 7, 10, 12, 13, 14, 15, 17, 18,
                  19, 24, 27, 28, 30, 32, 35, 37, 38]
     random.seed(0)
     #Cut down the python3 rng to the same precision as python2
     random.shuffle(self.dt_a, lambda:round(random.random(), 9))
     random.shuffle(self.dt_b, lambda:round(random.random(), 9))
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b)
     self.assertEqual(real_ans, ans)
Beispiel #6
0
def initialSW():
    """Construct initial estimate of hourly solar wind parameters"""
    st = dt.datetime(1989, 3, 12)
    en = dt.datetime(1989, 3, 15)
    hourly = getKondrashovSW()
    # Keep IMF By and n, set V to Boteler/Nagatsuma
    t_ssc1 = dt.datetime(1989, 3, 13, 1, 27)
    t_ssc2 = dt.datetime(1989, 3, 13, 7, 43)
    t_cme = dt.datetime(1989, 3, 13, 16)
    t_turn = dt.datetime(1989, 3, 14, 2)
    # Set Bx positive, in accordance with ISEE-3 data, Vy/Vz->0
    hourly['Bx'] = dm.dmfilled(hourly['By'].shape, fillval=3)
    hourly['Vy'] = dm.dmfilled(hourly['By'].shape, fillval=0)
    hourly['Vz'] = dm.dmfilled(hourly['By'].shape, fillval=0)
    # Before first SSC
    inds_before_1 = tb.tOverlapHalf([dt.datetime(1989, 3, 12), t_ssc1],
                                    hourly['DateTime'])
    hourly['V_sw'][inds_before_1] = 400
    # Between first and ssecond SSC
    inds_between_12 = tb.tOverlapHalf([t_ssc1, t_ssc2], hourly['DateTime'])
    hourly['V_sw'][inds_between_12] = 550
    # IMF turns north around 1989-03-14T02:00:00 according to inverse Burton and Kondrashov
    inds_mainphase = tb.tOverlapHalf([t_ssc2, t_turn], hourly['DateTime'])
    hourly['V_sw'][inds_mainphase] = 983
    # Then have speed decay towards IMP-8 measurement which is ballpark 820 km/s
    inds_rest = tb.tOverlapHalf([t_turn, hourly['DateTime'][-1]],
                                hourly['DateTime'])
    hourly['V_sw'][inds_rest] = np.linspace(983, 820, len(inds_rest))
    # Now we have speed, estimate temperature
    hourly['Plasma_temp'] = emp.getExpectedSWTemp(hourly['V_sw'],
                                                  model='XB15',
                                                  units='K')
    inds_cme = tb.tOverlapHalf([t_cme, en], hourly['DateTime'])
    hourly['Plasma_temp'][
        inds_cme] /= 3  # reduce by factor of 3 for CME-like temp
    # Get "Kondrashov VBs" using V from Boteler/Nagatsuma
    hourly['VBs_K'] = 1e-3 * hourly['V_sw'] * rectify(
        -1 * hourly['Bz'])  # mV/m
    # Now get VBs from inverse Burton
    ky_dat = kyo.fetch('dst', (st.year, st.month, st.day),
                       (en.year, en.month, en.day))
    inds = tb.tOverlapHalf([st, en], ky_dat['time'])
    # Pressure correct here using n and V
    hourly = calc_P(hourly)
    hourly['Dst'] = ky_dat['dst'][inds]
    dst_star = emp.getDststar(hourly, model='OBrien')
    hourly['VBs_OB'] = 1e-3 * inverseOBrienMcPherron(dst_star)
    # Make new Bz from VBs_OB
    hourly['Bz_OB'] = -1e3 * hourly['VBs_OB'] / hourly['V_sw']  # nT

    return hourly
Beispiel #7
0
 def test_tOverlapHalfSorted(self):
     """Get overlap of only one list, exploiting the sort"""
     real_ans = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b, presort=True)
     numpy.testing.assert_array_equal(real_ans, ans)
Beispiel #8
0
 def test_tOverlapHalf(self):
     """Get overlap of only one list"""
     real_ans = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b)
     self.assertEqual(real_ans, ans)
Beispiel #9
0
def get_omni(ticks, dbase='QDhourly', **kwargs):
    '''
    Returns Qin-Denton OMNI values, interpolated to any time-base from a default hourly resolution

    The update function in toolbox retrieves all available hourly Qin-Denton data, 
    and this function accesses that and interpolates to the given times,
    returning the OMNI values as a SpaceData (dict-like) with
    Kp, Dst, dens, velo, Pdyn, ByIMF, BzIMF, G1, G2, G3, etc.
    (see also http://www.dartmouth.edu/~rdenton/magpar/index.html and
    http://www.agu.org/pubs/crossref/2007/2006SW000296.shtml )

    Parameters
    ==========
    ticks : Ticktock class or array-like of datetimes
        time values for desired output

    dbase : str (optional)
        Select data source, options are 'QDhourly', 'OMNI2', 'Mergedhourly'
        Note - Custom data sources can be specified in the spacepy config file
        as described in the module documentation.

    Returns
    =======
    out : spacepy.datamodel.SpaceData
        containing all Qin-Denton values at times given by ticks

    Examples
    ========
    >>> import spacepy.time as spt
    >>> import spacepy.omni as om
    >>> ticks = spt.Ticktock(['2002-02-02T12:00:00', '2002-02-02T12:10:00'], 'ISO')
    >>> d = om.get_omni(ticks)
    >>> d.tree(levels=1)
    +
    |____ByIMF
    |____Bz1
    |____Bz2
    |____Bz3
    |____Bz4
    |____Bz5
    |____Bz6
    |____BzIMF
    |____DOY
    |____Dst
    |____G1
    |____G2
    |____G3
    |____Hr
    |____Kp
    |____Pdyn
    |____Qbits
    |____RDT
    |____UTC
    |____W1
    |____W2
    |____W3
    |____W4
    |____W5
    |____W6
    |____Year
    |____akp3
    |____dens
    |____ticks
    |____velo


    Notes
    =====
    Note about Qbits: If the status variable is 2, the quantity you are using is fairly well
    determined. If it is 1, the value has some connection to measured values, but is not directly
    measured. These values are still better than just using an average value, but not as good
    as those with the status variable equal to 2. If the status variable is 0, the quantity is
    based on average quantities, and the values listed are no better than an average value. The
    lower the status variable, the less confident you should be in the value.

    '''
    dbase_options = {'QDhourly'    : 1,
                     'OMNI2hourly' : 2,
                     'Mergedhourly': 3,
                     'Test'        : -9,
                     }

    if not isinstance(ticks, spt.Ticktock):
        try:
            ticks = spt.Ticktock(ticks, 'UTC')
        except:
            raise TypeError('get_omni: Input times must be a Ticktock object or a list of datetime objects')

    if not dbase in dbase_options:
        from spacepy import config
        if dbase in config:
            #If a dbase is specified that isn't a default, then it MUST be in the spacepy config
            qdpath = os.path.split(os.path.split(config[dbase])[0])[0]
            if not os.path.isdir(qdpath): raise IOError('Specified dbase ({0}) does not have a valid location ({1})'.format(dbase, config[dbase]))
            days = list(set([tt.date() for tt in ticks.UTC]))
            flist = ['']*len(days)
            fnpath, fnformat = os.path.split(config[dbase])
            for idx, day in enumerate(days):
                dp = fnpath.replace('YYYY', '{0}'.format(day.year))
                df = fnformat.replace('YYYY', '{0}'.format(day.year))
                df = df.replace('MM', '{0:02d}'.format(day.month))
                df = df.replace('DD', '{0:02d}'.format(day.day))
                flist[idx] = os.path.join(dp, df)
            if 'convert' in kwargs:
                convdict = kwargs['convert']
            else:
                convdict = True #set to True as default?
            if 'interp' not in kwargs:
                kwargs['interp'] = True
            data = readJSONheadedASCII(sorted(flist), convert=convdict)
            omniout = SpaceData()

            time_var = [var for var in ['DateTime', 'Time', 'Epoch', 'UTC'] if var in data]
            if time_var:
                use_t_var = time_var[0]
            else:
                #no obvious time variable in input files ... can't continue
                raise ValueError('No clear time variable in file')
            
            if kwargs['interp'] is True:    
                data['RDT'] = spt.Ticktock(data[use_t_var]).RDT
                keylist = sorted(data.keys())
                dum = keylist.pop(keylist.index(use_t_var))
                for key in keylist:
                    try:
                        omniout[key] = dmarray(np.interp(ticks.RDT, data['RDT'], data[key], left=np.NaN, right=np.NaN))
                        omniout[key].attrs = dmcopy(data[key].attrs)
                    except:
                        try:
                            omniout[key] = dmfilled([len(ticks.RDT), data[key].shape[1]], fillval=np.NaN, attrs=dmcopy(data[key].attrs))
                            for col in range(data[key].shape[1]):
                                omniout[key][:,col] = np.interp(ticks.RDT, data['RDT'], data[key][:,col], left=np.NaN, right=np.NaN)
                        except ValueError:
                            print('Failed to interpolate {0} to new time base, skipping variable'.format(key))
                        except IndexError:
                            print('Variable {0} appears to be non-record varying, skipping interpolation'.format(key))
                            omniout[key] = data[key]
                omniout['UTC'] = ticks.UTC 
            else:
                #Trim to specified times
                inds = tOverlapHalf([ticks[0].RDT, ticks[-1].RDT], spt.Ticktock(data['DateTime']).RDT)
                for key in data:
                    if len(inds) == len(data[key]):
                        omniout[key] = data[key][inds]
                    else: #is ancillary data
                        omniout[key] = data[key]
                #TODO: convert to same format as OMNI/QD read (or vice versa)
                omniout['UTC'] = omniout[use_t_var]
            return omniout
        else:
            raise IOError('Specified dbase ({0}) must be specified in spacepy.config'.format(dbase))

    def getattrs(hf, key):
        out = {}
        if hasattr(hf[key],'attrs'):
            for kk, value in hf[key].attrs.items():
                try:
                    out[kk] = value
                except:
                    pass
        return out

    def HrFromDT(indt):
        hour = indt.hour
        minute = indt.minute
        second = indt.second
        musecond = indt.microsecond
        return hour+(minute/60.0)+(second/3600.0)+(musecond/3600.0e3)

    import h5py as h5
    fname, QDkeylist, O2keylist = '', [], []
    omnivals = SpaceData()
    dbase_select = dbase_options[dbase]
    if dbase_select in [1, 3, -9]:
        if dbase_select > 0:
            ldb = 'QDhourly'
            fln = omnifln
        else:
            ldb = 'Test'
            fln = testfln
        with h5.File(fln, 'r') as hfile:
            QDkeylist = [kk for kk in hfile if kk not in ['Qbits', 'UTC']]
            st, en = ticks[0].RDT, ticks[-1].RDT
            ##check that requested requested times are within range of data
            enval, stval = omnirange(dbase=ldb)[1], omnirange(dbase=ldb)[0]
            if (ticks.UTC[0]>enval) or (ticks[-1]<stval):
                raise ValueError('Requested dates are outside data range')
            if (ticks.UTC[-1]>enval) or (ticks[0]<stval):
                print('Warning: Some requested dates are outside data range ({0})'.format(ldb))
            inds = tOverlapHalf([st, en], hfile['RDT'], presort=True) #returns an xrange
            inds = indsFromXrange(inds)
            if inds[0] < 1: inds[0] = 1
            sl_op = slice(inds[0]-1, inds[-1]+2)
    
            fname = ','.join([fname,hfile.filename])
            omnivals.attrs = getattrs(hfile, '/')
            for key in QDkeylist:
                omnivals[key] = dmarray(hfile[key][sl_op]) #TODO: add attrs from h5
                omnivals[key].attrs = getattrs(hfile, key)
            for key in hfile['Qbits']:
                omnivals['Qbits<--{0}'.format(key)] = dmarray(hfile['/Qbits/{0}'.format(key)][sl_op])
                omnivals['Qbits<--{0}'.format(key)].attrs = getattrs(hfile, '/Qbits/{0}'.format(key))
                QDkeylist.append('Qbits<--{0}'.format(key))

    if dbase_options[dbase] == 2 or dbase_options[dbase] == 3:
        ldb = 'OMNI2hourly'
        with h5.File(omni2fln) as hfile:
            O2keylist = [kk for kk in hfile if kk not in ['Epoch','RDT']]
            st, en = ticks[0].RDT, ticks[-1].RDT
            ##check that requested requested times are within range of data
            enval, stval = omnirange(dbase=ldb)[1], omnirange(dbase=ldb)[0]
            if (ticks[0].UTC>enval) or (ticks[-1]<stval):
                raise ValueError('Requested dates are outside data range')
            if (ticks[-1].UTC>enval) or (ticks[0]<stval):
                print('Warning: Some requested dates are outside data range ({0})'.format(ldb))
            inds = tOverlapHalf([st, en], hfile['RDT'], presort=True) #returns an xrange
            inds = indsFromXrange(inds)
            if inds[0] < 1: inds[0] = 1
            sl_op = slice(inds[0]-1, inds[-1]+2)
        
            fname = ','.join([fname,hfile.filename])
            omnivals.attrs = getattrs(hfile, '/') #TODO: This overwrites the previous set on Merged load... Fix!
            omnivals['RDT_OMNI'] = dmarray(hfile['RDT'][sl_op])
            for key in O2keylist:
                omnivals[key] = dmarray(hfile[key][sl_op]) #TODO: add attrs from h5
                omnivals[key].attrs = getattrs(hfile, key)

    if dbase_options[dbase] == 3:
        #prune "merged" SpaceData
        sigmas = [key for key in omnivals if 'sigma' in key]
        for sk in sigmas: del omnivals[sk]
        bees = [key for key in omnivals if re.search('B._', key)]
        for bs in bees: del omnivals[bs]
        aves = [key for key in omnivals if ('_ave' in key) or ('ave_' in key)]
        for av in aves: del omnivals[av]

    omniout = SpaceData(attrs=dmcopy(omnivals.attrs))
    omniout.attrs['filename'] = fname[1:]
    ###print('QDkeys: {0}\n\nO2keys: {1}'.format(QDkeylist, O2keylist))
    for key in sorted(omnivals.keys()):
        if key in O2keylist:
            omniout[key] = dmarray(np.interp(ticks.RDT, omnivals['RDT_OMNI'], omnivals[key], left=np.NaN, right=np.NaN))
            #set metadata -- assume this has been set properly in d/l'd file to match ECT-SOC files
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
        elif key in QDkeylist:
            omniout[key] = dmarray(np.interp(ticks.RDT, omnivals['RDT'], omnivals[key], left=np.NaN, right=np.NaN))
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
        if key == 'G3': #then we have all the Gs
            omniout['G'] = dmarray(np.vstack([omniout['G1'], omniout['G2'], omniout['G3']]).T)
            omniout['G'].attrs = dmcopy(omnivals['G1'].attrs)
            for i in range(1,4): del omniout['G{0}'.format(i)]
        if key == 'W6':
            omniout['W'] = dmarray(np.vstack([omniout['W1'], omniout['W2'], omniout['W3'], omniout['W4'], omniout['W5'], omniout['W6']]).T)
            omniout['W'].attrs = dmcopy(omnivals['W1'].attrs)
            for i in range(1,7): del omniout['W{0}'.format(i)]
        if 'Qbits' in key:
            #Qbits are integer vals, higher is better, so floor to get best representation of interpolated val
            omniout[key] = np.floor(omnivals[key]) 
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
            if 'G3' in key: #then we have all the Gs
                omniout['Qbits<--G'] = dmarray(np.vstack([omniout['Qbits<--G1'], omniout['Qbits<--G2'], omniout['Qbits<--G3']]).T)
                for i in range(1,4): del omniout['Qbits<--G{0}'.format(i)]
            if 'W6' in key:
                omniout['Qbits<--W'] = dmarray(np.vstack([omniout['Qbits<--W1'], omniout['Qbits<--W2'], omniout['Qbits<--W3'], omniout['Qbits<--W4'], omniout['Qbits<--W5'], omniout['Qbits<--W6']]).T)
                for i in range(1,7): del omniout['Qbits<--W{0}'.format(i)]

    omniout['ticks'] = ticks
    omniout['UTC'] = ticks.UTC
    omniout['Hr'] = dmarray([HrFromDT(val) for val in omniout['UTC']])
    omniout['Year'] = dmarray([val.year for val in omniout['UTC']])
    omniout = unflatten(omniout)

    return omniout
Beispiel #10
0
 def test_tOverlapHalfSorted(self):
     """Get overlap of only one list, exploiting the sort"""
     real_ans = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b, presort=True)
     numpy.testing.assert_array_equal(real_ans, ans)
Beispiel #11
0
def makeSW_v2():
    """Construct initial estimate of hourly solar wind parameters"""
    st = dt.datetime(1989, 3, 12)
    en = dt.datetime(1989, 3, 15)
    hourly = getKondrashovSW()
    # Keep IMF By and n, set V to Boteler/Nagatsuma
    t_ssc1 = dt.datetime(1989, 3, 13, 1, 27)
    t_ssc2 = dt.datetime(1989, 3, 13, 7, 43)
    t_cme = dt.datetime(1989, 3, 13, 16)
    t_turn = dt.datetime(1989, 3, 14, 2)
    # Set Bx positive, in accordance with ISEE-3 data, Vy/Vz->0
    hourly['Bx'] = dm.dmfilled(hourly['By'].shape, fillval=3)
    hourly['Vy'] = dm.dmfilled(hourly['By'].shape, fillval=0)
    hourly['Vz'] = dm.dmfilled(hourly['By'].shape, fillval=0)
    # Before first SSC
    inds_before_1 = tb.tOverlapHalf([dt.datetime(1989, 3, 12), t_ssc1],
                                    hourly['DateTime'])
    hourly['V_sw'][inds_before_1] = 400
    # Between first and ssecond SSC
    inds_between_12 = tb.tOverlapHalf([t_ssc1, t_ssc2], hourly['DateTime'])
    hourly['V_sw'][inds_between_12] = 550
    # IMF turns north around 1989-03-14T02:00:00 according to inverse Burton and Kondrashov
    inds_mainphase = tb.tOverlapHalf([t_ssc2, t_turn], hourly['DateTime'])
    hourly['V_sw'][inds_mainphase] = 983
    # Then have speed decay towards IMP-8 measurement which is ballpark 820 km/s
    inds_rest = tb.tOverlapHalf([t_turn, hourly['DateTime'][-1]],
                                hourly['DateTime'])
    hourly['V_sw'][inds_rest] = np.linspace(983, 820, len(inds_rest))
    # Now we have speed, estimate temperature
    hourly['Plasma_temp'] = emp.getExpectedSWTemp(hourly['V_sw'],
                                                  model='XB15',
                                                  units='K')
    inds_cme = tb.tOverlapHalf([t_cme, en], hourly['DateTime'])
    hourly['Plasma_temp'][
        inds_cme] /= 3  # reduce by factor of 3 for CME-like temp
    # Get "Kondrashov VBs" using V from Boteler/Nagatsuma
    hourly['VBs_K'] = 1e-3 * hourly['V_sw'] * rectify(
        -1 * hourly['Bz'])  # mV/m
    # Now get VBs from inverse Burton
    ky_dat = kyo.fetch('dst', (st.year, st.month, st.day),
                       (en.year, en.month, en.day))
    inds = tb.tOverlapHalf([st, en], ky_dat['time'])
    # Substitute density curve from Sept. 2017 (double shock)
    sep17 = pybats.ImfInput(
        filename=
        '/home/smorley/projects/github/advect1d/IMF_201709_advect_filt.dat',
        load=True)
    den_inds = tb.tOverlapHalf(
        [t_ssc1 - dt.timedelta(hours=25), hourly['DateTime'][-1]],
        hourly['DateTime'])
    nhours = len(den_inds)
    # Keep the opening 8 hours from Kondrashov (2017 event gets high)
    hourly['Den_P'][den_inds[9:]] = 2 + (sep17['rho'][::60][9:nhours] * 2)
    # After shocks, ensure number density doesn't drop below 10 (keeps M_A over 2)
    after_ssc2 = hourly['DateTime'] > t_ssc2
    under_lim = hourly['Den_P'] <= 10
    limit_inds = np.logical_and(after_ssc2, under_lim)
    hourly['Den_P'][limit_inds] = 10
    # Pressure correct here using n and V
    hourly = calc_P(hourly)
    hourly['Dst'] = ky_dat['dst'][inds]
    dst_star = emp.getDststar(hourly, model='OBrien')
    hourly['VBs_OB'] = 1e-3 * inverseOBrienMcPherron(dst_star)
    # Make new Bz from VBs_OB
    hourly['Bz_OB'] = -1e3 * hourly['VBs_OB'] / hourly['V_sw']  # nT

    return hourly
Beispiel #12
0
 def test_tOverlapHalf(self):
     """Get overlap of only one list"""
     real_ans = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
     ans = tb.tOverlapHalf(self.dt_a, self.dt_b)
     self.assertEqual(real_ans, ans)
Beispiel #13
0
    def plotSummary(self,
                    timerange=None,
                    coord_sys=None,
                    fig_target=None,
                    spec=False,
                    orbit_params=(False, True),
                    **kwargs):
        """Generate summary plot of AE9/AP9/SPM data loaded
        
        spec : if True, plot spectrogram instead of flux/fluence lineplot, requires 'ecol' keyword
        """
        if timerange:
            if isinstance(timerange, spt.Ticktock):
                t1 = timerange.UTC[0]
                t2 = timerange.UTC[-1]
            elif isinstance(timerange[0], dt.datetime):
                t1 = timerange[0]
                t2 = timerange[-1]
            else:
                raise TypeError('Incorrect data type provided for timerange')
            # now select subset
            i_use = tb.tOverlapHalf([t1, t2], self['Epoch'])
            t_use = self['Epoch'][i_use]
            c_use = self['Coords'][i_use]
            f_use = self[self.attrs['varname']][i_use, ...]
        else:
            t_use = self['Epoch']
            c_use = self['Coords']
            f_use = self[self.attrs['varname']]

        if coord_sys and (coord_sys.upper() != c_use.attrs['COORD_SYS']):
            # TODO: We assume cartesian, make flexible so can take spherical
            cx = spc.Coords(c_use, c_use.attrs['COORD_SYS'], 'car')
            cx.ticks = spt.Ticktock(t_use)
            cx = cx.convert(coord_sys.upper(), 'car').data
        else:
            coord_sys = c_use.attrs['COORD_SYS']
            cx = c_use
        sys_subs = r'$_{' + coord_sys + r'}$'

        splot.style('spacepy')
        if orbit_params[0]:
            landscape = orbit_params[1]
            locs = [121, 122] if landscape else [211, 212]
        else:
            locs = [223, 224]
            landscape = True
        if fig_target:
            fig, ax1 = splot.set_target(fig_target, loc=locs[0])
        else:
            fig, ax1 = splot.set_target(fig_target,
                                        figsize=(8, 8),
                                        loc=locs[0])
        fig, ax2 = splot.set_target(fig, loc=locs[1])

        ax1 = self._makeOrbitAxis(cx[:, 0], cx[:, 1], ax1)
        ax2 = self._makeOrbitAxis(cx[:, 0], cx[:, 2], ax2)
        if landscape:
            ax1.set_xlabel('X{0} [{1}]'.format(sys_subs,
                                               self['Coords'].attrs['UNITS']))
        ax2.set_xlabel('X{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax1.set_ylabel('Y{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax2.set_ylabel('Z{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax1xl, ax1yl, ax2xl, ax2yl = ax1.get_xlim(), ax1.get_ylim(
        ), ax2.get_xlim(), ax2.get_ylim()
        maxabslim = np.max(np.abs([ax1xl, ax1yl, ax2xl, ax2yl]))
        if np.abs((ax1.get_xlim()[1] - ax1.get_xlim()[0])) < 1:
            refpt = maxabslim
            ax1.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax1.set_ylim(ax1.get_xlim())
            refpt = ax2.get_xlim()[0]
            ax2.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax2.set_ylim(ax1.get_xlim())
        else:
            ax1.set_xlim([-maxabslim, maxabslim])
            ax1.set_ylim([-maxabslim, maxabslim])
            ax2.set_xlim([-maxabslim, maxabslim])
        ax2.set_ylim(ax2.get_xlim())
        ax1.invert_yaxis()
        ax1.invert_xaxis()
        ax2.invert_xaxis()
        ax1.set_aspect('equal')
        ax2.set_aspect('equal')

        if not orbit_params[0]:
            ax3 = splot.plt.subplot2grid((2, 2), (0, 0), colspan=2)
            if not spec:
                l3 = ax3.semilogy(t_use, f_use)
                ylab = '{0} ['.format(self.attrs['varname']) + re.sub(
                    '(\^[\d|-]*)+', _grp2mathmode,
                    self[self.attrs['varname']].attrs['UNITS']) + ']'
                ax3.set_ylabel(ylab)
                for ll, nn in zip(l3, self['Energy']):
                    ll.set_label('{0} {1}'.format(
                        nn, self['Energy'].attrs['UNITS']))
                ncol = len(self['Energy']) // 2 if len(
                    self['Energy']) <= 6 else 3
                leg = ax3.legend(loc='center',
                                 bbox_to_anchor=(0.5, 1),
                                 ncol=ncol,
                                 frameon=True,
                                 framealpha=0.5)
                lims3 = ax3.get_ylim()
                newupper = 10**(np.log10(lims3[0]) +
                                (np.log10(lims3[1] / lims3[0]) * 1.125))
                ax3.set_ylim([lims3[0], newupper])
                splot.applySmartTimeTicks(ax3, t_use)
                fig.tight_layout()
                pos3 = ax3.get_position()
                ax3.set_position(
                    [pos3.x0, pos3.y0, pos3.width, pos3.height * 0.8])
                # fig.suptitle('{model_type}\n'.format(**self.attrs) +
                #             '{0} - {1}'.format(t_use[0].isoformat()[:19], t_use[-1].isoformat()[:19]))
            else:
                if timerange:
                    raise NotImplementedError(
                        'Time range selection not yet implemented for spectrograms'
                    )
                pos3 = ax3.get_position()
                ax3.set_position(
                    [pos3.x0, pos3.y0, pos3.width, pos3.height * 0.9])
                ecol = kwargs['ecol'] if 'ecol' in kwargs else 0
                ax3 = self.plotSpectrogram(target=ax3, ecol=ecol)
                splot.plt.subplots_adjust(wspace=0.3)
                pos1 = ax1.get_position()
                ax1.set_position([pos3.x0, pos1.y0, pos1.width, pos1.height])

        splot.revert_style()
        return fig
Beispiel #14
0
import datetime

import numpy as np

import spacepy.toolbox as tb
import spacepy.pycdf as pycdf
from spacepy.datamodel import SpaceData, dmarray

cdf = pycdf.CDF('poes_n15_short.cdf')

plotTime = np.asarray(
    [datetime.datetime(2000, 11, 1),
     datetime.datetime(2000, 12, 1)])

rng = tb.tOverlapHalf(plotTime, cdf['EPOCH'], presort=True)
ind1 = rng[0]
ind2 = rng[-1]

data = SpaceData()
data['Epoch'] = dmarray(cdf['EPOCH'][ind1:ind2])
data['lValue'] = dmarray(cdf['lValue'][ind1:ind2])
data['mepOmni'] = dmarray(cdf['mepOmni'][ind1:ind2])[:, 0]
#data['Epoch'] = cdf['EPOCH'][ind1:ind2]
#data['lValue'] = cdf['lValue'][ind1:ind2]

cdf.close()

avgt = datetime.timedelta(minutes=300)  #time scale to average over in minutes
Tbins = np.asarray([
    plotTime[0] + stp * avgt for stp in xrange(
        np.long(np.ceil(plotTime.ptp().total_seconds() /
Beispiel #15
0
def get_omni(ticks, dbase='QDhourly', **kwargs):
    '''
    Returns Qin-Denton OMNI values, interpolated to any time-base from a default hourly resolution

    The update function in toolbox retrieves all available hourly Qin-Denton data, 
    and this function accesses that and interpolates to the given times,
    returning the OMNI values as a SpaceData (dict-like) with
    Kp, Dst, dens, velo, Pdyn, ByIMF, BzIMF, G1, G2, G3, etc.
    (see also http://www.dartmouth.edu/~rdenton/magpar/index.html and
    http://www.agu.org/pubs/crossref/2007/2006SW000296.shtml )

    Parameters
    ==========
    ticks : Ticktock class or array-like of datetimes
        time values for desired output

    dbase : str (optional)
        Select data source, options are 'QDhourly', 'OMNI2hourly', 'Mergedhourly'
        Note - Custom data sources can be specified in the spacepy config file
        as described in the module documentation.

    Returns
    =======
    out : spacepy.datamodel.SpaceData
        containing all Qin-Denton values at times given by ticks

    Examples
    ========
    >>> import spacepy.time as spt
    >>> import spacepy.omni as om
    >>> ticks = spt.Ticktock(['2002-02-02T12:00:00', '2002-02-02T12:10:00'], 'ISO')
    >>> d = om.get_omni(ticks)
    >>> d.tree(levels=1)
    +
    |____ByIMF
    |____Bz1
    |____Bz2
    |____Bz3
    |____Bz4
    |____Bz5
    |____Bz6
    |____BzIMF
    |____DOY
    |____Dst
    |____G1
    |____G2
    |____G3
    |____Hr
    |____Kp
    |____Pdyn
    |____Qbits
    |____RDT
    |____UTC
    |____W1
    |____W2
    |____W3
    |____W4
    |____W5
    |____W6
    |____Year
    |____akp3
    |____dens
    |____ticks
    |____velo


    Notes
    =====
    Note about Qbits: If the status variable is 2, the quantity you are using is fairly well
    determined. If it is 1, the value has some connection to measured values, but is not directly
    measured. These values are still better than just using an average value, but not as good
    as those with the status variable equal to 2. If the status variable is 0, the quantity is
    based on average quantities, and the values listed are no better than an average value. The
    lower the status variable, the less confident you should be in the value.

    '''
    dbase_options = {
        'QDhourly': 1,
        'OMNI2hourly': 2,
        'Mergedhourly': 3,
        'Test': -9,
    }

    if not isinstance(ticks, spt.Ticktock):
        try:
            ticks = spt.Ticktock(ticks, 'UTC')
        except:
            raise TypeError(
                'get_omni: Input times must be a Ticktock object or a list of datetime objects'
            )

    if not dbase in dbase_options:
        from spacepy import config
        if dbase in config:
            #If a dbase is specified that isn't a default, then it MUST be in the spacepy config
            qdpath = os.path.split(os.path.split(config[dbase])[0])[0]
            if not os.path.isdir(qdpath):
                raise IOError(
                    'Specified dbase ({0}) does not have a valid location ({1})'
                    .format(dbase, config[dbase]))
            days = list(set([tt.date() for tt in ticks.UTC]))
            flist = [''] * len(days)
            fnpath, fnformat = os.path.split(config[dbase])
            for idx, day in enumerate(days):
                dp = fnpath.replace('YYYY', '{0}'.format(day.year))
                df = fnformat.replace('YYYY', '{0}'.format(day.year))
                df = df.replace('MM', '{0:02d}'.format(day.month))
                df = df.replace('DD', '{0:02d}'.format(day.day))
                flist[idx] = os.path.join(dp, df)
            if 'convert' in kwargs:
                convdict = kwargs['convert']
            else:
                convdict = True  #set to True as default?
            if 'interp' not in kwargs:
                kwargs['interp'] = True
            data = readJSONheadedASCII(sorted(flist), convert=convdict)
            omniout = SpaceData()

            time_var = [
                var for var in ['DateTime', 'Time', 'Epoch', 'UTC']
                if var in data
            ]
            if time_var:
                use_t_var = time_var[0]
            else:
                #no obvious time variable in input files ... can't continue
                raise ValueError('No clear time variable in file')

            if kwargs['interp'] is True:
                data['RDT'] = spt.Ticktock(data[use_t_var]).RDT
                keylist = sorted(data.keys())
                dum = keylist.pop(keylist.index(use_t_var))
                for key in keylist:
                    try:
                        omniout[key] = dmarray(
                            np.interp(ticks.RDT,
                                      data['RDT'],
                                      data[key],
                                      left=np.NaN,
                                      right=np.NaN))
                        omniout[key].attrs = dmcopy(data[key].attrs)
                    except:
                        try:
                            omniout[key] = dmfilled(
                                [len(ticks.RDT), data[key].shape[1]],
                                fillval=np.NaN,
                                attrs=dmcopy(data[key].attrs))
                            for col in range(data[key].shape[1]):
                                omniout[key][:,
                                             col] = np.interp(ticks.RDT,
                                                              data['RDT'],
                                                              data[key][:,
                                                                        col],
                                                              left=np.NaN,
                                                              right=np.NaN)
                        except ValueError:
                            print(
                                'Failed to interpolate {0} to new time base, skipping variable'
                                .format(key))
                        except IndexError:
                            print(
                                'Variable {0} appears to be non-record varying, skipping interpolation'
                                .format(key))
                            omniout[key] = data[key]
                omniout['UTC'] = ticks.UTC
            else:
                #Trim to specified times
                inds = tOverlapHalf([ticks[0].RDT, ticks[-1].RDT],
                                    spt.Ticktock(data['DateTime']).RDT)
                for key in data:
                    if len(inds) == len(data[key]):
                        omniout[key] = data[key][inds]
                    else:  #is ancillary data
                        omniout[key] = data[key]
                #TODO: convert to same format as OMNI/QD read (or vice versa)
                omniout['UTC'] = omniout[use_t_var]
            return omniout
        else:
            raise IOError(
                'Specified dbase ({0}) must be specified in spacepy.config'.
                format(dbase))

    def getattrs(hf, key):
        out = {}
        if hasattr(hf[key], 'attrs'):
            for kk, value in hf[key].attrs.items():
                try:
                    out[kk] = value
                except:
                    pass
        return out

    def HrFromDT(indt):
        hour = indt.hour
        minute = indt.minute
        second = indt.second
        musecond = indt.microsecond
        return hour + (minute / 60.0) + (second / 3600.0) + (musecond /
                                                             3600.0e3)

    import h5py as h5
    fname, QDkeylist, O2keylist = '', [], []
    omnivals = SpaceData()
    dbase_select = dbase_options[dbase]
    if dbase_select in [1, 3, -9]:
        if dbase_select > 0:
            ldb = 'QDhourly'
            fln = omnifln
        else:
            ldb = 'Test'
            fln = testfln
        with h5.File(fln, 'r') as hfile:
            QDkeylist = [kk for kk in hfile if kk not in ['Qbits', 'UTC']]
            st, en = ticks[0].RDT, ticks[-1].RDT
            ##check that requested requested times are within range of data
            enval, stval = omnirange(dbase=ldb)[1], omnirange(dbase=ldb)[0]
            if (ticks.UTC[0] > enval) or (ticks[-1] < stval):
                raise ValueError('Requested dates are outside data range')
            if (ticks.UTC[-1] > enval) or (ticks[0] < stval):
                print(
                    'Warning: Some requested dates are outside data range ({0})'
                    .format(ldb))
            inds = tOverlapHalf([st, en], hfile['RDT'],
                                presort=True)  #returns an xrange
            inds = indsFromXrange(inds)
            if inds[0] < 1: inds[0] = 1
            sl_op = slice(inds[0] - 1, inds[-1] + 2)

            fname = ','.join([fname, hfile.filename])
            omnivals.attrs = getattrs(hfile, '/')
            for key in QDkeylist:
                omnivals[key] = dmarray(
                    hfile[key][sl_op])  #TODO: add attrs from h5
                omnivals[key].attrs = getattrs(hfile, key)
            for key in hfile['Qbits']:
                omnivals['Qbits<--{0}'.format(key)] = dmarray(
                    hfile['/Qbits/{0}'.format(key)][sl_op])
                omnivals['Qbits<--{0}'.format(key)].attrs = getattrs(
                    hfile, '/Qbits/{0}'.format(key))
                QDkeylist.append('Qbits<--{0}'.format(key))

    if dbase_options[dbase] == 2 or dbase_options[dbase] == 3:
        ldb = 'OMNI2hourly'
        with h5.File(omni2fln) as hfile:
            O2keylist = [kk for kk in hfile if kk not in ['Epoch', 'RDT']]
            st, en = ticks[0].RDT, ticks[-1].RDT
            ##check that requested requested times are within range of data
            enval, stval = omnirange(dbase=ldb)[1], omnirange(dbase=ldb)[0]
            if (ticks[0].UTC > enval) or (ticks[-1] < stval):
                raise ValueError('Requested dates are outside data range')
            if (ticks[-1].UTC > enval) or (ticks[0] < stval):
                print(
                    'Warning: Some requested dates are outside data range ({0})'
                    .format(ldb))
            inds = tOverlapHalf([st, en], hfile['RDT'],
                                presort=True)  #returns an xrange
            inds = indsFromXrange(inds)
            if inds[0] < 1: inds[0] = 1
            sl_op = slice(inds[0] - 1, inds[-1] + 2)

            fname = ','.join([fname, hfile.filename])
            omnivals.attrs = getattrs(
                hfile, '/'
            )  #TODO: This overwrites the previous set on Merged load... Fix!
            omnivals['RDT_OMNI'] = dmarray(hfile['RDT'][sl_op])
            for key in O2keylist:
                omnivals[key] = dmarray(
                    hfile[key][sl_op])  #TODO: add attrs from h5
                omnivals[key].attrs = getattrs(hfile, key)

    if dbase_options[dbase] == 3:
        #prune "merged" SpaceData
        sigmas = [key for key in omnivals if 'sigma' in key]
        for sk in sigmas:
            del omnivals[sk]
        bees = [key for key in omnivals if re.search('B._', key)]
        for bs in bees:
            del omnivals[bs]
        aves = [key for key in omnivals if ('_ave' in key) or ('ave_' in key)]
        for av in aves:
            del omnivals[av]

    omniout = SpaceData(attrs=dmcopy(omnivals.attrs))
    omniout.attrs['filename'] = fname[1:]
    ###print('QDkeys: {0}\n\nO2keys: {1}'.format(QDkeylist, O2keylist))
    for key in sorted(omnivals.keys()):
        if key in O2keylist:
            omniout[key] = dmarray(
                np.interp(ticks.RDT,
                          omnivals['RDT_OMNI'],
                          omnivals[key],
                          left=np.NaN,
                          right=np.NaN))
            #set metadata -- assume this has been set properly in d/l'd file to match ECT-SOC files
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
        elif key in QDkeylist:
            omniout[key] = dmarray(
                np.interp(ticks.RDT,
                          omnivals['RDT'],
                          omnivals[key],
                          left=np.NaN,
                          right=np.NaN))
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
        if key == 'G3':  #then we have all the Gs
            omniout['G'] = dmarray(
                np.vstack([omniout['G1'], omniout['G2'], omniout['G3']]).T)
            omniout['G'].attrs = dmcopy(omnivals['G1'].attrs)
            for i in range(1, 4):
                del omniout['G{0}'.format(i)]
        if key == 'W6':
            omniout['W'] = dmarray(
                np.vstack([
                    omniout['W1'], omniout['W2'], omniout['W3'], omniout['W4'],
                    omniout['W5'], omniout['W6']
                ]).T)
            omniout['W'].attrs = dmcopy(omnivals['W1'].attrs)
            for i in range(1, 7):
                del omniout['W{0}'.format(i)]
        if 'Qbits' in key:
            #Qbits are integer vals, higher is better, so floor to get best representation of interpolated val
            omniout[key] = np.floor(omnivals[key])
            omniout[key].attrs = dmcopy(omnivals[key].attrs)
            if 'G3' in key:  #then we have all the Gs
                omniout['Qbits<--G'] = dmarray(
                    np.vstack([
                        omniout['Qbits<--G1'], omniout['Qbits<--G2'],
                        omniout['Qbits<--G3']
                    ]).T)
                for i in range(1, 4):
                    del omniout['Qbits<--G{0}'.format(i)]
            if 'W6' in key:
                omniout['Qbits<--W'] = dmarray(
                    np.vstack([
                        omniout['Qbits<--W1'], omniout['Qbits<--W2'],
                        omniout['Qbits<--W3'], omniout['Qbits<--W4'],
                        omniout['Qbits<--W5'], omniout['Qbits<--W6']
                    ]).T)
                for i in range(1, 7):
                    del omniout['Qbits<--W{0}'.format(i)]

    omniout['ticks'] = ticks
    omniout['UTC'] = ticks.UTC
    omniout['Hr'] = dmarray([HrFromDT(val) for val in omniout['UTC']])
    omniout['Year'] = dmarray([val.year for val in omniout['UTC']])
    omniout = unflatten(omniout)

    return omniout
Beispiel #16
0
    def plotSummary(self, timerange=None, coord_sys=None, fig_target=None, spec=False, orbit_params=(False, True),
                    **kwargs):
        """Generate summary plot of AE9/AP9/SPM data loaded
        
        spec : if True, plot spectrogram instead of flux/fluence lineplot, requires 'ecol' keyword
        """
        if timerange:
            if isinstance(timerange, spt.Ticktock):
                t1 = timerange.UTC[0]
                t2 = timerange.UTC[-1]
            elif isinstance(timerange[0], dt.datetime):
                t1 = timerange[0]
                t2 = timerange[-1]
            else:
                raise TypeError('Incorrect data type provided for timerange')
            # now select subset
            i_use = tb.tOverlapHalf([t1, t2], self['Epoch'])
            t_use = self['Epoch'][i_use]
            c_use = self['Coords'][i_use]
            f_use = self[self.attrs['varname']][i_use, ...]
        else:
            t_use = self['Epoch']
            c_use = self['Coords']
            f_use = self[self.attrs['varname']]

        if coord_sys and (coord_sys.upper() != c_use.attrs['COORD_SYS']):
            # TODO: We assume cartesian, make flexible so can take spherical
            cx = spc.Coords(c_use, c_use.attrs['COORD_SYS'], 'car')
            cx.ticks = spt.Ticktock(t_use)
            cx = cx.convert(coord_sys.upper(), 'car').data
        else:
            coord_sys = c_use.attrs['COORD_SYS']
            cx = c_use
        sys_subs = r'$_{' + coord_sys + r'}$'

        splot.style('spacepy')
        if orbit_params[0]:
            landscape = orbit_params[1]
            locs = [121, 122] if landscape else [211, 212]
        else:
            locs = [223, 224]
            landscape = True
        if fig_target:
            fig, ax1 = splot.set_target(fig_target, loc=locs[0])
        else:
            fig, ax1 = splot.set_target(fig_target, figsize=(8, 8), loc=locs[0])
        fig, ax2 = splot.set_target(fig, loc=locs[1])

        ax1 = self._makeOrbitAxis(cx[:, 0], cx[:, 1], ax1)
        ax2 = self._makeOrbitAxis(cx[:, 0], cx[:, 2], ax2)
        if landscape: ax1.set_xlabel('X{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax2.set_xlabel('X{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax1.set_ylabel('Y{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax2.set_ylabel('Z{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax1xl, ax1yl, ax2xl, ax2yl = ax1.get_xlim(), ax1.get_ylim(), ax2.get_xlim(), ax2.get_ylim()
        maxabslim = np.max(np.abs([ax1xl, ax1yl, ax2xl, ax2yl]))
        if np.abs((ax1.get_xlim()[1] - ax1.get_xlim()[0])) < 1:
            refpt = maxabslim
            ax1.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax1.set_ylim(ax1.get_xlim())
            refpt = ax2.get_xlim()[0]
            ax2.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax2.set_ylim(ax1.get_xlim())
        else:
            ax1.set_xlim([-maxabslim, maxabslim])
            ax1.set_ylim([-maxabslim, maxabslim])
            ax2.set_xlim([-maxabslim, maxabslim])
        ax2.set_ylim(ax2.get_xlim())
        ax1.invert_yaxis()
        ax1.invert_xaxis()
        ax2.invert_xaxis()
        ax1.set_aspect('equal')
        ax2.set_aspect('equal')

        if not orbit_params[0]:
            ax3 = splot.plt.subplot2grid((2, 2), (0, 0), colspan=2)
            if not spec:
                l3 = ax3.semilogy(t_use, f_use)
                ylab = '{0} ['.format(self.attrs['varname']) + re.sub('(\^[\d|-]*)+', _grp2mathmode,
                                                                      self[self.attrs['varname']].attrs['UNITS']) + ']'
                ax3.set_ylabel(ylab)
                for ll, nn in zip(l3, self['Energy']):
                    ll.set_label('{0} {1}'.format(nn, self['Energy'].attrs['UNITS']))
                ncol = len(self['Energy']) // 2 if len(self['Energy']) <= 6 else 3
                leg = ax3.legend(loc='center', bbox_to_anchor=(0.5, 1), ncol=ncol,
                                 frameon=True, framealpha=0.5)
                lims3 = ax3.get_ylim()
                newupper = 10 ** (np.log10(lims3[0]) + (np.log10(lims3[1] / lims3[0]) * 1.125))
                ax3.set_ylim([lims3[0], newupper])
                splot.applySmartTimeTicks(ax3, t_use)
                fig.tight_layout()
                pos3 = ax3.get_position()
                ax3.set_position([pos3.x0, pos3.y0, pos3.width, pos3.height * 0.8])
                # fig.suptitle('{model_type}\n'.format(**self.attrs) +
                #             '{0} - {1}'.format(t_use[0].isoformat()[:19], t_use[-1].isoformat()[:19]))
            else:
                if timerange: raise NotImplementedError('Time range selection not yet implemented for spectrograms')
                pos3 = ax3.get_position()
                ax3.set_position([pos3.x0, pos3.y0, pos3.width, pos3.height * 0.9])
                ecol = kwargs['ecol'] if 'ecol' in kwargs else 0
                ax3 = self.plotSpectrogram(target=ax3, ecol=ecol)
                splot.plt.subplots_adjust(wspace=0.3)
                pos1 = ax1.get_position()
                ax1.set_position([pos3.x0, pos1.y0, pos1.width, pos1.height])

        splot.revert_style()
        return fig
Beispiel #17
0
 fig, ax = plotMSBS(data=swdata89, angles=(-145, 145), mp=False, bs=True)
 # add IMP8 traj
 import os
 import datetime as dt
 import swtools
 import utils
 import spacepy.datamanager as dman
 import spacepy.toolbox as tb
 datapath = os.path.abspath(os.path.join('..', 'ref_data', '1989'))
 # When plotting, use spacepy.datamanager to insert fill between contiguous regions
 mit_pl = swtools.readIMP8plasmafile(os.path.join(datapath, 'imp8.data.1989.060.090'))
 # Now insert fill at gaps for plotting positions
 mit_t, mit_x = dman.insert_fill(np.asarray(mit_pl['time']), np.asarray(mit_pl['pos_gse'][:,0]))
 mit_t, mit_y = dman.insert_fill(np.asarray(mit_pl['time']), np.asarray(mit_pl['pos_gse'][:,1]))
 mit_t, mit_z = dman.insert_fill(np.asarray(mit_pl['time']), np.asarray(mit_pl['pos_gse'][:,2]))
 inds13 = tb.tOverlapHalf([dt.datetime(1989,3,13), dt.datetime(1989,3,14)], mit_t)
 inds14 = tb.tOverlapHalf([dt.datetime(1989,3,14), dt.datetime(1989,3,15)], mit_t)
 inds1314 = tb.tOverlapHalf([dt.datetime(1989,3,13), dt.datetime(1989,3,15)], mit_t)
 # Get position in aberrated GSE to compare to bow shock model
 pos_agse1314 = np.zeros((len(mit_x),3))
 r_sat_agse = np.zeros_like(mit_x)
 r_bs_agse = np.zeros_like(mit_x)
 xhat = np.array([1, 0, 0])
 for idx in inds1314:
     pos_gse1314 = np.array([mit_x[idx], mit_y[idx], mit_z[idx]])
     pos_agse1314[idx] = agse_convert(pos_gse1314, swdata89)
     r_sat_agse[idx] = np.linalg.norm(pos_agse1314[idx])
     sattheta = utils.angle_between_vectors(xhat, pos_agse1314[idx])
     r_bs_agse[idx] = bowshock(swdata89, sattheta)
 # And now plot the orbit
 ax.plot(mit_x[inds13], mit_y[inds13], label='IMP8 3/13')
Beispiel #18
0
import datetime

import numpy as np

import spacepy.toolbox as tb
import spacepy.pycdf as pycdf
from spacepy.datamodel import SpaceData, dmarray

cdf = pycdf.CDF('poes_n15_short.cdf')

plotTime = np.asarray([datetime.datetime(2000, 11, 1), datetime.datetime(2000, 12, 1)])

rng = tb.tOverlapHalf(plotTime, cdf['EPOCH'], presort=True)
ind1 = rng[0]
ind2 = rng[-1]

data = SpaceData()
data['Epoch'] = dmarray(cdf['EPOCH'][ind1:ind2])
data['lValue'] = dmarray(cdf['lValue'][ind1:ind2])
data['mepOmni'] = dmarray(cdf['mepOmni'][ind1:ind2])[:,0]
#data['Epoch'] = cdf['EPOCH'][ind1:ind2]
#data['lValue'] = cdf['lValue'][ind1:ind2]


cdf.close()

avgt = datetime.timedelta(minutes=300)              #time scale to average over in minutes
Tbins = np.asarray([plotTime[0] + stp * avgt for
                    stp in xrange(np.long(np.ceil(plotTime.ptp().total_seconds()/avgt.total_seconds())))])