コード例 #1
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_magdi(self):
        '''
        GITM 3DION and 3DMAG files contain the magnetic field in
        North-East-Vertical coordinates.  This routine computes the magnetic
        inclination and declination.
        '''
        import math

        mag = None
        # Test to determine the type of file we have
        if(self.attrs['file'].find("ION") > 0
           or self.attrs['file'].find("MAG") > 0):
            mag = self
        else:
            if not 'magfile' in self.attrs:
                print("No 3D MAG/ION file associated with this GITM Binary")
            elif(self.attrs['magfile'].find("ION") <= 0 and
                 self.attrs['magfile'].find("MAG") <= 0):
                print("No 3D MAG/ION file associated with this GITM Binary")
            else:
                mag = GitmBin(self.attrs['magfile'])

        if mag is not None:
            dec_frac = mag['B.F. East'] / mag['B.F. North']
            inc_sign = -1.0 * mag['B.F. Vertical'] / abs(mag['B.F. Vertical'])
            inc_pmag = mag['B.F. North']**2 + mag['B.F. East']**2

            for ilon in range(self.attrs['nLon']):
                for ilat in range(self.attrs['nLat']):
                    for ialt,df in enumerate(dec_frac[ilon,ilat]):
                        dec_frac[ilon,ilat,ialt] = math.atan(df) * 180.0 / np.pi
                        i = (inc_sign[ilon,ilat,ialt]
                             * math.sqrt(inc_pmag[ilon,ilat,ialt])
                             / mag['B.F. Magnitude'][ilon,ilat,ialt])
                        inc_pmag[ilon,ilat,ialt] = math.acos(i) * 180.0 / np.pi
                        if inc_pmag[ilon,ilat,ialt] > 90.0:
                            inc_pmag[ilon,ilat,ialt] -= 180.0

            self['Declination'] = dmarray.copy(dec_frac)
            self['Declination'].attrs = {"name":"Declination", "scale":"linear",
                                         "units":"degrees"}
            self['Inclination'] = dmarray.copy(inc_pmag)
            self['Inclination'].attrs = {"name":"Inclination", "scale":"linear",
                                         "units":"degrees"}
            del dec_frac, inc_sign, inc_pmag

            if not 'B.F. East' in self:
                self['B.F. East'] = dmarray.copy(mag['B.F. East'])
                self['B.F. North'] = dmarray.copy(mag['B.F. North'])
                self['B.F. Vertical'] = dmarray.copy(mag['B.F. Vertical'])
                self['B.F. Magnitude'] = dmarray.copy(mag['B.F. Magnitude'])
            if not 'Magnetic Latitude' in self:
                self['Magnetic Latitude']=dmarray.copy(mag['Magnetic Latitude'])
                self['Magnetic Longitude']=dmarray.copy(mag['Magnetic Longitude'])
コード例 #2
0
ファイル: gitm.py プロジェクト: aaronjridley/GITM
    def calc_magdi(self):
        """
        GITM 3DION and 3DMAG files contain the magnetic field in
        North-East-Vertical coordinates.  This routine computes the magnetic
        inclination and declination.
        """
        import math

        mag = None
        # Test to determine the type of file we have
        if self.attrs["file"].find("ION") > 0 or self.attrs["file"].find("MAG") > 0:
            mag = self
        else:
            if not self.attrs.has_key("magfile"):
                print "No 3D MAG/ION file associated with this GITM Binary"
            elif self.attrs["magfile"].find("ION") <= 0 and self.attrs["magfile"].find("MAG") <= 0:
                print "No 3D MAG/ION file associated with this GITM Binary"
            else:
                mag = GitmBin(self.attrs["magfile"])

        if mag is not None:
            dec_frac = mag["B.F. East"] / mag["B.F. North"]
            inc_sign = -1.0 * mag["B.F. Vertical"] / abs(mag["B.F. Vertical"])
            inc_pmag = mag["B.F. North"] ** 2 + mag["B.F. East"] ** 2

            for ilon in range(self.attrs["nLon"]):
                for ilat in range(self.attrs["nLat"]):
                    for ialt, df in enumerate(dec_frac[ilon, ilat]):
                        dec_frac[ilon, ilat, ialt] = math.atan(df) * 180.0 / np.pi
                        i = (
                            inc_sign[ilon, ilat, ialt]
                            * math.sqrt(inc_pmag[ilon, ilat, ialt])
                            / mag["B.F. Magnitude"][ilon, ilat, ialt]
                        )
                        inc_pmag[ilon, ilat, ialt] = math.acos(i) * 180.0 / np.pi
                        if inc_pmag[ilon, ilat, ialt] > 90.0:
                            inc_pmag[ilon, ilat, ialt] -= 180.0

            self["Declination"] = dmarray.copy(dec_frac)
            self["Declination"].attrs = {"name": "Declination", "scale": "linear", "units": "degrees"}
            self["Inclination"] = dmarray.copy(inc_pmag)
            self["Inclination"].attrs = {"name": "Inclination", "scale": "linear", "units": "degrees"}
            del dec_frac, inc_sign, inc_pmag

            if not self.has_key("B.F. East"):
                self["B.F. East"] = dmarray.copy(mag["B.F. East"])
                self["B.F. North"] = dmarray.copy(mag["B.F. North"])
                self["B.F. Vertical"] = dmarray.copy(mag["B.F. Vertical"])
                self["B.F. Magnitude"] = dmarray.copy(mag["B.F. Magnitude"])
            if not self.has_key("Magnetic Latitude"):
                self["Magnetic Latitude"] = dmarray.copy(mag["Magnetic Latitude"])
                self["Magnetic Longitude"] = dmarray.copy(mag["Magnetic Longitude"])
コード例 #3
0
ファイル: gitm.py プロジェクト: guodj/work
    def append_data(self, varlist):
        '''
        A routine to append more variables to an existing GITM data structure.
        New variables can only be added from the same file (specified in
        the 'file' attribute).
        '''

        temp = GitmBin(self.attrs['file'], varlist, False)

        for nkey in temp.keys():
            if not nkey in self:
                self[nkey] = dmarray.copy(temp[nkey])
コード例 #4
0
ファイル: gitm.py プロジェクト: guodj/work
    def append_data(self, varlist):
        '''
        A routine to append more variables to an existing GITM data structure.
        New variables can only be added from the same file (specified in
        the 'file' attribute).
        '''

        temp = GitmBin(self.attrs['file'], varlist, False)

        for nkey in temp.keys():
            if not nkey in self:
                self[nkey] = dmarray.copy(temp[nkey])
コード例 #5
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_2dion(self):
        '''
        A routine to calculate the 2D ionospheric parameters: VTEC, hmF2, NmF2.
        To perform these calculations, electron density ("e-") must be one of
        the available data types.
        '''
        import scipy.integrate as integ
        from scipy.interpolate import interp1d
        from scipy.signal import argrelextrema

        calc_tec = False
        if 'e-' in self:
            if 'VTEC' in self is False:
                calc_tec = True
                self['VTEC'] = dmarray(self['e-'] * 1.0e-16,
                                       attrs={
                                           'units': 'TECU',
                                           'scale': 'linear',
                                           'name': 'Vertical TEC'
                                       })
            self['NmF2'] = dmarray.copy(self['e-'])
            self['NmF2'].attrs['name'] = 'N$_m$F$_2$'
            self['hmF2'] = dmarray(self['Altitude'] / 1000.0,
                                   attrs={
                                       'units': 'km',
                                       'scale': 'linear',
                                       'name': 'h$_m$F$_2$'
                                   })
            alt = np.linspace(min(self['hmF2'][0, 0, 2:-2]),
                              max(self['hmF2'][0, 0, 2:-2]), 1000)

            for ilon in range(self.attrs['nLon']):
                for ilat in range(self.attrs['nLat']):
                    if calc_tec is True:
                        # Integrate electron density over altitude
                        vtec = integ.simps(self['VTEC'][ilon, ilat, 2:-2],
                                           self['Altitude'][ilon, ilat,
                                                            2:-2], "avg")
                        self['VTEC'][ilon, ilat, :] = vtec

                    # Interpolate over the electron density altitude profile
                    eprof = interp1d(self['hmF2'][ilon, ilat, 2:-2],
                                     self['NmF2'][ilon, ilat, 2:-2],
                                     kind="cubic")
                    try:
                        edens = eprof(alt)
                    except:
                        alt = np.linspace(min(self['hmF2'][ilon, ilat, 2:-2]),
                                          max(self['hmF2'][ilon, ilat, 2:-2]),
                                          1000)
                        edens = eprof(alt)

                    # Find the local maxima of the electron density profile
                    emax = argrelextrema(edens, np.greater)
                    emax_list = list(emax[0])
                    saddle = False
                    if len(emax_list) == 0:
                        # No local maxima were found, try identifying
                        # saddle points
                        saddle = True
                    elif len(emax_list) == 1:
                        if max(edens) == edens[emax_list[0]]:
                            # Only one maxima exists and is realistic. Sometimes
                            # a profile will have inflection points instead of
                            # local maxima and this can confuse the routine
                            self['NmF2'][ilon, ilat, :] = edens[emax_list[0]]
                            self['hmF2'][ilon, ilat, :] = alt[emax_list[0]]
                        else:
                            saddle = True
                    elif alt[emax_list[-1]] < 120.0:
                        saddle = True
                    else:
                        # More than one maxima exists.  Seperate hmF2 from hmF1
                        # and spurious local maxima
                        NmF2 = list(edens[emax_list])
                        HmF2 = list(alt[emax_list])

                        # If the global maximum is over 200 km,
                        # this is the F2 peak
                        eindex = NmF2.index(max(NmF2))
                        if HmF2[eindex] <= 200.0 and HmF2[eindex] == min(HmF2):
                            # The global max may be the F1 peak, see if the
                            # secondary (or lessor) maxima is at the upper
                            # limit of the model.  If so, remove this point
                            # from consideration
                            if max(HmF2) > self['hmF2'][ilon, ilat, -5]:
                                eindex = HmF2.index(max(HmF2))
                                emax_list.pop(eindex)
                                NmF2.pop(eindex)
                                HmF2.pop(eindex)
                                eindex = NmF2.index(max(NmF2))

                            if len(emax_list) > 1:
                                # If there are multiple maxima after the upper
                                # boundary has been removed, choose the largest
                                # maxima above 200 km since the hmF1 is often
                                # larger than the hmF2
                                emax_list.pop(eindex)
                                NmF2.pop(eindex)
                                eindex = NmF2.index(max(NmF2))

                        # Set the hmF2 and NmF2
                        self['NmF2'][ilon, ilat, :] = edens[emax_list[eindex]]
                        self['hmF2'][ilon, ilat, :] = alt[emax_list[eindex]]

                    if saddle:
                        # It is difficult to find saddle points.  Examine
                        # the rate of change of density
                        delta_alt = alt[1] - alt[0]  # Equally spaced
                        edens_dot = np.diff(edens) / delta_alt

                        # Identify inflection points by looking for
                        # minima in the derivative of electron density.
                        edot_min = argrelextrema(edens_dot, np.less)
                        emin_list = list(edot_min[0])
                        edens_min = list(edens[emin_list])
                        emax = np.max(edens_min)
                        eindex = emin_list[edens_min.index(emax)]

                        # Assign the inflection with the largest
                        # electron density to the ion peak
                        self['NmF2'][ilon, ilat, :] = edens[eindex]
                        self['hmF2'][ilon, ilat, :] = alt[eindex]
コード例 #6
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_magvel(self):
        '''
        Gitm 3DIon files contain the magnetic coordinates that allow the
        field-aligned and field-perpendicular velocities to be computed.
        The 3DIon file must be from the same run as the 3DAll file so that
        the geographic grid is the same.  If a 3D Ion file was not produced
        in the original run, don't fret!  You can get one by using the same
        UAM.in file.  Unless the magnetic field is varying secularly, you
        can get away with producing just one 3DIon file.  It is better to have
        a matching 3D Ion file for every 3D All file, however.
        '''
        import math
        import string
        import sys

        ion = None
        # If this is a 3D ION file we don't need a mag file
        if self.attrs['file'].find("ION") > 0:
            ion = self
        else:
            if not 'magfile' in self.attrs:
                print("No 3D MAG/ION file associated with this GITM Binary")
            elif (self.attrs['magfile'].find("ION") <= 0
                  and self.attrs['magfile'].find("MAG") <= 0):
                print("No 3D MAG/ION file associated with this GITM Binary")
            else:
                ion = GitmBin(self.attrs['magfile'])

        # Compute the field-aligned unit vector in East, North,
        # and Vertical coordinates
        if ion:
            bhat_e = ion['B.F. East'] / ion['B.F. Magnitude']
            bhat_n = ion['B.F. North'] / ion['B.F. Magnitude']
            bhat_v = ion['B.F. Vertical'] / ion['B.F. Magnitude']

            # Compute the zonal unit vector in East, North, Vertical coord

            mag = np.sqrt(
                np.square(ion['B.F. East']) + np.square(ion['B.F. North']))

            zhat_e = ion['B.F. North'] / mag
            zhat_n = ion['B.F. East'] / mag
            # zhat_v is identically zero

            # Compute the meridional unit vector in East, North, Vertical coord

            mhat_e = (-ion['B.F. East'] * ion['B.F. Vertical'] /
                      (mag * ion['B.F. Magnitude']))
            mhat_n = (-ion['B.F. North'] * ion['B.F. Vertical'] /
                      (mag * ion['B.F. Magnitude']))
            mhat_v = mag / ion['B.F. Magnitude']

            # Compute the magnetic coordinate velocities for each overlapping
            # latitude, longitude, and altitude.  Also include the mag coord.

            for item in self.keys():
                if (string.find(item, "V!") >= 0
                        or string.find(item, "Gravity") >= 0
                        or string.find(item, "PressGrad") >= 0):
                    sp = string.split(item)
                    units = self[item].attrs['units']
                    scale = self[item].attrs['scale']
                    # extract the non-directional part of the name
                    if not sp[0] in self:
                        east = string.join([sp[0], "(east)"], " ")
                        north = string.join([sp[0], "(north)"], " ")
                        up = string.join([sp[0], "(up)"], " ")
                        par = string.join([sp[0], "(par)"], " ")
                        zon = string.join([sp[0], "(zon)"], " ")
                        mer = string.join([sp[0], "(mer)"], " ")
                        name = self[east].attrs['name']

                        vp = bhat_e * self[east] + bhat_n * self[
                            north] + bhat_v * self[up]
                        vz = zhat_e * self[east] + zhat_n * self[north]
                        vm = mhat_e * self[east] + mhat_n * self[
                            north] + mhat_v * self[up]
                    elif sp[0].find("Gravity") >= 0:
                        par = string.join([sp[0], "(par)"], " ")
                        zon = string.join([sp[0], "(zon)"], " ")
                        mer = string.join([sp[0], "(mer)"], " ")
                        name = "%s$_{east}$" % (self[item].attrs['name'])

                        vp = bhat_v * self[item]
                        vz = 0.0 * self[item]
                        vm = mhat_v * self[item]

                    self[par] = dmarray.copy(vp)
                    self[par].attrs = {
                        'units':
                        '%s{\mathdefault{,\,positive\,mag\,north}}' % (units),
                        'scale':
                        scale,
                        'name':
                        name.replace("east", "\parallel")
                    }
                    self[zon] = dmarray.copy(vz)
                    self[zon].attrs = {
                        'units':
                        '%s{\mathdefault{,\,positive\,east}}' % (units),
                        'scale': scale,
                        'name': name.replace("east", "zon")
                    }
                    self[mer] = dmarray.copy(vm)
                    self[mer].attrs = {
                        'units': '%s{\mathdefault{,\,positive\,up}}' % (units),
                        'scale': scale,
                        'name': name.replace("east", "mer")
                    }

            if not 'B.F. East' in self:
                self['B.F. East'] = dmarray.copy(ion['B.F. East'])
                self['B.F. North'] = dmarray.copy(ion['B.F. North'])
                self['B.F. Vertical'] = dmarray.copy(ion['B.F. Vertical'])
                self['B.F. Magnitude'] = dmarray.copy(ion['B.F. Magnitude'])
            if not 'Magnetic Latitude' in self:
                self['Magnetic Latitude'] = dmarray.copy(
                    ion['Magnetic Latitude'])
                self['Magnetic Longitude'] = dmarray.copy(
                    ion['Magnetic Longitude'])
コード例 #7
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_magdi(self):
        '''
        GITM 3DION and 3DMAG files contain the magnetic field in
        North-East-Vertical coordinates.  This routine computes the magnetic
        inclination and declination.
        '''
        import math

        mag = None
        # Test to determine the type of file we have
        if (self.attrs['file'].find("ION") > 0
                or self.attrs['file'].find("MAG") > 0):
            mag = self
        else:
            if not 'magfile' in self.attrs:
                print("No 3D MAG/ION file associated with this GITM Binary")
            elif (self.attrs['magfile'].find("ION") <= 0
                  and self.attrs['magfile'].find("MAG") <= 0):
                print("No 3D MAG/ION file associated with this GITM Binary")
            else:
                mag = GitmBin(self.attrs['magfile'])

        if mag is not None:
            dec_frac = mag['B.F. East'] / mag['B.F. North']
            inc_sign = -1.0 * mag['B.F. Vertical'] / abs(mag['B.F. Vertical'])
            inc_pmag = mag['B.F. North']**2 + mag['B.F. East']**2

            for ilon in range(self.attrs['nLon']):
                for ilat in range(self.attrs['nLat']):
                    for ialt, df in enumerate(dec_frac[ilon, ilat]):
                        dec_frac[ilon, ilat,
                                 ialt] = math.atan(df) * 180.0 / np.pi
                        i = (inc_sign[ilon, ilat, ialt] *
                             math.sqrt(inc_pmag[ilon, ilat, ialt]) /
                             mag['B.F. Magnitude'][ilon, ilat, ialt])
                        inc_pmag[ilon, ilat,
                                 ialt] = math.acos(i) * 180.0 / np.pi
                        if inc_pmag[ilon, ilat, ialt] > 90.0:
                            inc_pmag[ilon, ilat, ialt] -= 180.0

            self['Declination'] = dmarray.copy(dec_frac)
            self['Declination'].attrs = {
                "name": "Declination",
                "scale": "linear",
                "units": "degrees"
            }
            self['Inclination'] = dmarray.copy(inc_pmag)
            self['Inclination'].attrs = {
                "name": "Inclination",
                "scale": "linear",
                "units": "degrees"
            }
            del dec_frac, inc_sign, inc_pmag

            if not 'B.F. East' in self:
                self['B.F. East'] = dmarray.copy(mag['B.F. East'])
                self['B.F. North'] = dmarray.copy(mag['B.F. North'])
                self['B.F. Vertical'] = dmarray.copy(mag['B.F. Vertical'])
                self['B.F. Magnitude'] = dmarray.copy(mag['B.F. Magnitude'])
            if not 'Magnetic Latitude' in self:
                self['Magnetic Latitude'] = dmarray.copy(
                    mag['Magnetic Latitude'])
                self['Magnetic Longitude'] = dmarray.copy(
                    mag['Magnetic Longitude'])
コード例 #8
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_2dion(self):
        '''
        A routine to calculate the 2D ionospheric parameters: VTEC, hmF2, NmF2.
        To perform these calculations, electron density ("e-") must be one of
        the available data types.
        '''
        import scipy.integrate as integ
        from scipy.interpolate import interp1d
        from scipy.signal import argrelextrema

        calc_tec = False
        if 'e-' in self:
            if 'VTEC' in self is False:
                calc_tec = True
                self['VTEC'] = dmarray(self['e-'] * 1.0e-16,
                                       attrs={'units':'TECU', 'scale':'linear',
                                              'name':'Vertical TEC'})
            self['NmF2'] = dmarray.copy(self['e-'])
            self['NmF2'].attrs['name'] = 'N$_m$F$_2$'
            self['hmF2'] = dmarray(self['Altitude'] / 1000.0,
                                   attrs={'units':'km', 'scale':'linear',
                                          'name':'h$_m$F$_2$'})
            alt = np.linspace(min(self['hmF2'][0,0,2:-2]),
                              max(self['hmF2'][0,0,2:-2]),1000)

            for ilon in range(self.attrs['nLon']):
                for ilat in range(self.attrs['nLat']):
                    if calc_tec is True:
                        # Integrate electron density over altitude
                        vtec = integ.simps(self['VTEC'][ilon,ilat,2:-2],
                                           self['Altitude'][ilon,ilat,2:-2],
                                           "avg")
                        self['VTEC'][ilon,ilat,:] = vtec

                    # Interpolate over the electron density altitude profile
                    eprof = interp1d(self['hmF2'][ilon,ilat,2:-2],
                                     self['NmF2'][ilon,ilat,2:-2], kind="cubic")
                    try:
                        edens = eprof(alt)
                    except:
                        alt = np.linspace(min(self['hmF2'][ilon,ilat,2:-2]),
                                          max(self['hmF2'][ilon,ilat,2:-2]),
                                          1000)
                        edens = eprof(alt)

                    # Find the local maxima of the electron density profile
                    emax = argrelextrema(edens, np.greater)
                    emax_list = list(emax[0])
                    saddle = False
                    if len(emax_list) == 0:
                        # No local maxima were found, try identifying
                        # saddle points
                        saddle = True
                    elif len(emax_list) == 1:
                        if max(edens) == edens[emax_list[0]]:
                            # Only one maxima exists and is realistic. Sometimes
                            # a profile will have inflection points instead of
                            # local maxima and this can confuse the routine
                            self['NmF2'][ilon,ilat,:] = edens[emax_list[0]]
                            self['hmF2'][ilon,ilat,:] = alt[emax_list[0]]
                        else:
                            saddle = True
                    elif alt[emax_list[-1]] < 120.0:
                        saddle = True
                    else:
                        # More than one maxima exists.  Seperate hmF2 from hmF1
                        # and spurious local maxima
                        NmF2 = list(edens[emax_list])
                        HmF2 = list(alt[emax_list])

                        # If the global maximum is over 200 km,
                        # this is the F2 peak
                        eindex = NmF2.index(max(NmF2))
                        if HmF2[eindex] <= 200.0 and HmF2[eindex] == min(HmF2):
                            # The global max may be the F1 peak, see if the
                            # secondary (or lessor) maxima is at the upper
                            # limit of the model.  If so, remove this point
                            # from consideration
                            if max(HmF2) > self['hmF2'][ilon,ilat,-5]:
                                eindex = HmF2.index(max(HmF2))
                                emax_list.pop(eindex)
                                NmF2.pop(eindex)
                                HmF2.pop(eindex)
                                eindex = NmF2.index(max(NmF2))

                            if len(emax_list) > 1:
                                # If there are multiple maxima after the upper
                                # boundary has been removed, choose the largest
                                # maxima above 200 km since the hmF1 is often
                                # larger than the hmF2
                                emax_list.pop(eindex)
                                NmF2.pop(eindex)
                                eindex = NmF2.index(max(NmF2))

                        # Set the hmF2 and NmF2
                        self['NmF2'][ilon,ilat,:] = edens[emax_list[eindex]]
                        self['hmF2'][ilon,ilat,:] = alt[emax_list[eindex]]

                    if saddle:
                        # It is difficult to find saddle points.  Examine
                        # the rate of change of density
                        delta_alt = alt[1] - alt[0] # Equally spaced
                        edens_dot = np.diff(edens) / delta_alt

                        # Identify inflection points by looking for
                        # minima in the derivative of electron density.
                        edot_min = argrelextrema(edens_dot, np.less)
                        emin_list = list(edot_min[0])
                        edens_min = list(edens[emin_list])
                        emax = np.max(edens_min)
                        eindex = emin_list[edens_min.index(emax)]

                        # Assign the inflection with the largest
                        # electron density to the ion peak
                        self['NmF2'][ilon,ilat,:] = edens[eindex]
                        self['hmF2'][ilon,ilat,:] = alt[eindex]
コード例 #9
0
ファイル: gitm.py プロジェクト: guodj/work
    def calc_magvel(self):
        '''
        Gitm 3DIon files contain the magnetic coordinates that allow the
        field-aligned and field-perpendicular velocities to be computed.
        The 3DIon file must be from the same run as the 3DAll file so that
        the geographic grid is the same.  If a 3D Ion file was not produced
        in the original run, don't fret!  You can get one by using the same
        UAM.in file.  Unless the magnetic field is varying secularly, you
        can get away with producing just one 3DIon file.  It is better to have
        a matching 3D Ion file for every 3D All file, however.
        '''
        import math
        import string
        import sys

        ion = None
        # If this is a 3D ION file we don't need a mag file
        if self.attrs['file'].find("ION") > 0:
            ion = self
        else:
            if not 'magfile' in self.attrs:
                print("No 3D MAG/ION file associated with this GITM Binary")
            elif(self.attrs['magfile'].find("ION") <= 0 and
                 self.attrs['magfile'].find("MAG") <= 0):
                print("No 3D MAG/ION file associated with this GITM Binary")
            else:
                ion = GitmBin(self.attrs['magfile'])

        # Compute the field-aligned unit vector in East, North,
        # and Vertical coordinates
        if ion:
            bhat_e = ion['B.F. East'] / ion['B.F. Magnitude']
            bhat_n = ion['B.F. North'] / ion['B.F. Magnitude']
            bhat_v = ion['B.F. Vertical'] / ion['B.F. Magnitude']

            # Compute the zonal unit vector in East, North, Vertical coord

            mag = np.sqrt(np.square(ion['B.F. East'])
                          + np.square(ion['B.F. North']))

            zhat_e = ion['B.F. North'] / mag
            zhat_n = ion['B.F. East'] / mag
            # zhat_v is identically zero

            # Compute the meridional unit vector in East, North, Vertical coord

            mhat_e = (-ion['B.F. East']*ion['B.F. Vertical']
                       / (mag * ion['B.F. Magnitude']))
            mhat_n = (-ion['B.F. North']*ion['B.F. Vertical']
                       / (mag * ion['B.F. Magnitude']))
            mhat_v = mag / ion['B.F. Magnitude']

            # Compute the magnetic coordinate velocities for each overlapping
            # latitude, longitude, and altitude.  Also include the mag coord.

            for item in self.keys():
                if(string.find(item, "V!") >= 0 or
                   string.find(item, "Gravity") >= 0 or
                   string.find(item, "PressGrad") >= 0):
                    sp = string.split(item)
                    units = self[item].attrs['units']
                    scale = self[item].attrs['scale']
                    # extract the non-directional part of the name
                    if not sp[0] in self:
                        east = string.join([sp[0], "(east)"], " ")
                        north = string.join([sp[0], "(north)"], " ")
                        up = string.join([sp[0], "(up)"], " ")
                        par = string.join([sp[0], "(par)"], " ")
                        zon = string.join([sp[0], "(zon)"], " ")
                        mer = string.join([sp[0], "(mer)"], " ")
                        name = self[east].attrs['name']

                        vp=bhat_e*self[east]+bhat_n*self[north]+bhat_v*self[up]
                        vz=zhat_e*self[east]+zhat_n*self[north]
                        vm=mhat_e*self[east]+mhat_n*self[north]+mhat_v*self[up]
                    elif sp[0].find("Gravity") >= 0:
                        par = string.join([sp[0], "(par)"], " ")
                        zon = string.join([sp[0], "(zon)"], " ")
                        mer = string.join([sp[0], "(mer)"], " ")
                        name = "%s$_{east}$" % (self[item].attrs['name'])

                        vp=bhat_v*self[item]
                        vz=0.0*self[item]
                        vm=mhat_v*self[item]

                    self[par] = dmarray.copy(vp)
                    self[par].attrs = {'units':'%s{\mathdefault{,\,positive\,mag\,north}}'%(units), 'scale':scale, 'name':name.replace("east", "\parallel")}
                    self[zon] = dmarray.copy(vz)
                    self[zon].attrs = {'units':'%s{\mathdefault{,\,positive\,east}}'%(units), 'scale':scale, 'name':name.replace("east", "zon")}
                    self[mer] = dmarray.copy(vm)
                    self[mer].attrs = {'units':'%s{\mathdefault{,\,positive\,up}}'%(units), 'scale':scale, 'name':name.replace("east", "mer")}

            if not 'B.F. East' in self:
                self['B.F. East'] = dmarray.copy(ion['B.F. East'])
                self['B.F. North'] = dmarray.copy(ion['B.F. North'])
                self['B.F. Vertical'] = dmarray.copy(ion['B.F. Vertical'])
                self['B.F. Magnitude'] = dmarray.copy(ion['B.F. Magnitude'])
            if not 'Magnetic Latitude' in self:
                self['Magnetic Latitude'] = dmarray.copy(ion['Magnetic Latitude'])
                self['Magnetic Longitude'] = dmarray.copy(ion['Magnetic Longitude'])