Example #1
0
 def __init__(self, filename):
     """
     :param str filename:
         Name of the catalogue file in ndk format
     """
     self.filename = filename
     self.catalogue = GCMTCatalogue()
Example #2
0
 def __init__(self, filename):
     """
     :param str filename:
         Name of the catalogue file in ndk format
     """
     self.filename = filename
     self.catalogue = GCMTCatalogue()
Example #3
0
class ParseNDKtoGCMT(object):
    """
    Implements the parser to read a file in ndk format to the GCMT catalogue
    """
    def __init__(self, filename):
        """
        :param str filename:
            Name of the catalogue file in ndk format
        """
        self.filename = filename
        self.catalogue = GCMTCatalogue()

    def read_file(self, start_year=None, end_year=None, use_centroid=None):
        """
        Reads the file
        """
        raw_data = getlines(self.filename)
        num_lines = len(raw_data)
        if ((float(num_lines) / 5.) - float(num_lines / 5)) > 1E-9:
            raise IOError('GCMT represented by 5 lines - number in file not'
                          ' a multiple of 5!')
        self.catalogue.number_gcmts = num_lines // 5
        self.catalogue.gcmts = [None] * self.catalogue.number_gcmts
        # Pre-allocates list
        id0 = 0
        print('Parsing catalogue ...')
        for iloc in range(0, self.catalogue.number_gcmts):
            self.catalogue.gcmts[iloc] = self.read_ndk_event(raw_data, id0)
            id0 += 5
        print('complete. Contains %s moment tensors' %
              self.catalogue.get_number_tensors())
        if not start_year:
            min_years = []
            min_years = [
                cent.centroid.date.year for cent in self.catalogue.gcmts
            ]
            self.catalogue.start_year = np.min(min_years)

        if not end_year:
            max_years = []
            max_years = [
                cent.centroid.date.year for cent in self.catalogue.gcmts
            ]
            self.catalogue.end_year = np.max(max_years)
        self.to_hmtk(use_centroid)
        return self.catalogue

    def read_ndk_event(self, raw_data, id0):
        """
        Reads a 5-line batch of data into a set of GCMTs
        """
        gcmt = GCMTEvent()
        # Get hypocentre
        ndkstring = raw_data[id0].rstrip('\n')
        gcmt.hypocentre = self._read_hypocentre_from_ndk_string(ndkstring)

        # GCMT metadata
        ndkstring = raw_data[id0 + 1].rstrip('\n')
        gcmt = self._get_metadata_from_ndk_string(gcmt, ndkstring)

        # Get Centroid
        ndkstring = raw_data[id0 + 2].rstrip('\n')
        gcmt.centroid = self._read_centroid_from_ndk_string(
            ndkstring, gcmt.hypocentre)

        # Get Moment Tensor
        ndkstring = raw_data[id0 + 3].rstrip('\n')
        gcmt.moment_tensor = self._get_moment_tensor_from_ndk_string(ndkstring)

        # Get principal axes
        ndkstring = raw_data[id0 + 4].rstrip('\n')
        gcmt.principal_axes = self._get_principal_axes_from_ndk_string(
            ndkstring[3:48], exponent=gcmt.moment_tensor.exponent)

        # Get Nodal Planes
        gcmt.nodal_planes = self._get_nodal_planes_from_ndk_string(
            ndkstring[57:])

        # Get Moment and Magnitude
        gcmt.moment, gcmt.version, gcmt.magnitude = \
            self._get_moment_from_ndk_string(ndkstring,
                                             gcmt.moment_tensor.exponent)

        return gcmt

    def to_hmtk(self, use_centroid=True):
        '''
        Convert the content of the GCMT catalogue to a HMTK 
        catalogue. 
        '''

        self._preallocate_data_dict()
        for iloc, gcmt in enumerate(self.catalogue.gcmts):
            self.catalogue.data['eventID'][iloc] = iloc

            if use_centroid:
                self.catalogue.data['year'][iloc] = \
                    gcmt.centroid.date.year
                self.catalogue.data['month'][iloc] = \
                    gcmt.centroid.date.month
                self.catalogue.data['day'][iloc] = \
                    gcmt.centroid.date.day
                self.catalogue.data['hour'][iloc] = \
                    gcmt.centroid.time.hour
                self.catalogue.data['minute'][iloc] = \
                    gcmt.centroid.time.minute
                self.catalogue.data['second'][iloc] = \
                    gcmt.centroid.time.second
                self.catalogue.data['longitude'][iloc] = \
                    gcmt.centroid.longitude
                self.catalogue.data['latitude'][iloc] = \
                    gcmt.centroid.latitude
                self.catalogue.data['depth'][iloc] = \
                    gcmt.centroid.depth
            else:
                self.catalogue.data['year'][iloc] = \
                    gcmt.hypocentre.date.year
                self.catalogue.data['month'][iloc] = \
                    gcmt.hypocentre.date.month
                self.catalogue.data['day'][iloc] = \
                    gcmt.hypocentre.date.day
                self.catalogue.data['hour'][iloc] = \
                    gcmt.hypocentre.time.hour
                self.catalogue.data['minute'][iloc] = \
                    gcmt.hypocentre.time.minute
                self.catalogue.data['second'][iloc] = \
                    gcmt.hypocentre.time.second
                self.catalogue.data['longitude'][iloc] = \
                    gcmt.hypocentre.longitude
                self.catalogue.data['latitude'][iloc] = \
                    gcmt.hypocentre.latitude
                self.catalogue.data['depth'][iloc] = \
                    gcmt.hypocentre.depth
            # Moment, magnitude and relative errors
            self.catalogue.data['moment'][iloc] = gcmt.moment
            self.catalogue.data['magnitude'][iloc] = gcmt.magnitude
            self.catalogue.data['f_clvd'][iloc] = gcmt.f_clvd
            self.catalogue.data['e_rel'][iloc] = gcmt.e_rel
            self.catalogue.data['centroidID'][iloc] = gcmt.identifier
            # Nodal planes
            self.catalogue.data['strike1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['strike']
            self.catalogue.data['dip1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['dip']
            self.catalogue.data['rake1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['rake']
            self.catalogue.data['strike2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['strike']
            self.catalogue.data['dip2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['dip']
            self.catalogue.data['rake2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['rake']
            # Principal axes
            self.catalogue.data['eigenvalue_b'][iloc] = \
                gcmt.principal_axes.b_axis['eigenvalue']
            self.catalogue.data['azimuth_b'][iloc] = \
                gcmt.principal_axes.b_axis['azimuth']
            self.catalogue.data['plunge_b'][iloc] = \
                gcmt.principal_axes.b_axis['plunge']
            self.catalogue.data['eigenvalue_p'][iloc] = \
                gcmt.principal_axes.p_axis['eigenvalue']
            self.catalogue.data['azimuth_p'][iloc] = \
                gcmt.principal_axes.p_axis['azimuth']
            self.catalogue.data['plunge_p'][iloc] = \
                gcmt.principal_axes.p_axis['plunge']
            self.catalogue.data['eigenvalue_t'][iloc] = \
                gcmt.principal_axes.t_axis['eigenvalue']
            self.catalogue.data['azimuth_t'][iloc] = \
                gcmt.principal_axes.t_axis['azimuth']
            self.catalogue.data['plunge_t'][iloc] = \
                gcmt.principal_axes.t_axis['plunge']
        return self.catalogue

    def _preallocate_data_dict(self):
        """
        """
        nvals = self.catalogue.get_number_tensors()
        for key in self.catalogue.TOTAL_ATTRIBUTE_LIST:
            if key in self.catalogue.STRING_ATTRIBUTE_LIST:
                self.catalogue.data[key] = [None for i in range(0, nvals)]
            elif key in self.catalogue.INT_ATTRIBUTE_LIST:
                self.catalogue.data[key] = np.zeros(nvals, dtype=int)
            else:
                self.catalogue.data[key] = np.zeros(nvals, dtype=float)

    def _read_hypocentre_from_ndk_string(self, linestring):
        """
        Reads the hypocentre data from the ndk string to return an
        instance of the GCMTHypocentre class
        """
        hypo = GCMTHypocentre()
        hypo.source = linestring[0:4]
        hypo.date = _read_date_from_string(linestring[5:15])
        hypo.time = _read_time_from_string(linestring[16:26])
        hypo.latitude = float(linestring[27:33])
        hypo.longitude = float(linestring[34:41])
        hypo.depth = float(linestring[42:47])
        magnitudes = [float(x) for x in linestring[48:55].split(' ')]
        if magnitudes[0] > 0.:
            hypo.m_b = magnitudes[0]
        if magnitudes[1] > 0.:
            hypo.m_s = magnitudes[1]
        hypo.location = linestring[56:]
        return hypo

    def _get_metadata_from_ndk_string(self, gcmt, ndk_string):
        """
        Reads the GCMT metadata from line 2 of the ndk batch
        """
        gcmt.identifier = ndk_string[:16]
        inversion_data = re.split('[A-Z:]+', ndk_string[17:61])
        gcmt.metadata['BODY'] = [float(x) for x in inversion_data[1].split()]
        gcmt.metadata['SURFACE'] = [
            float(x) for x in inversion_data[2].split()
        ]
        gcmt.metadata['MANTLE'] = [float(x) for x in inversion_data[3].split()]
        further_meta = re.split('[: ]+', ndk_string[62:])
        gcmt.metadata['CMT'] = int(further_meta[1])
        gcmt.metadata['FUNCTION'] = {
            'TYPE': further_meta[2],
            'DURATION': float(further_meta[3])
        }
        return gcmt

    def _read_centroid_from_ndk_string(self, ndk_string, hypocentre):
        """
        Reads the centroid data from the ndk string to return an
        instance of the GCMTCentroid class
        :param str ndk_string:
            String of data (line 3 of ndk format)
        :param hypocentre:
            Instance of the GCMTHypocentre class
        """
        centroid = GCMTCentroid(hypocentre.date, hypocentre.time)

        data = ndk_string[:58].split()
        centroid.centroid_type = data[0].rstrip(':')
        data = [float(x) for x in data[1:]]
        time_diff = data[0]
        if fabs(time_diff) > 1E-6:
            centroid._get_centroid_time(time_diff)
        centroid.time_error = data[1]
        centroid.latitude = data[2]
        centroid.latitude_error = data[3]
        centroid.longitude = data[4]
        centroid.longitude_error = data[5]
        centroid.depth = data[6]
        centroid.depth_error = data[7]
        centroid.depth_type = ndk_string[59:63]
        centroid.centroid_id = ndk_string[64:]
        return centroid

    def _get_moment_tensor_from_ndk_string(self, ndk_string):
        """
        Reads the moment tensor from the ndk_string and returns an instance of
        the GCMTMomentTensor class.
        By default the ndk format uses the Up, South, East (USE) reference
        system.
        """
        moment_tensor = GCMTMomentTensor('USE')
        tensor_data = _read_moment_tensor_from_ndk_string(ndk_string, 'USE')
        moment_tensor.tensor = tensor_data[0]
        moment_tensor.tensor_sigma = tensor_data[1]
        moment_tensor.exponent = tensor_data[2]
        return moment_tensor

    def _get_principal_axes_from_ndk_string(self, ndk_string, exponent):
        """
        Gets the principal axes from the ndk string and returns an instance
        of the GCMTPrincipalAxes class
        """
        axes = GCMTPrincipalAxes()
        # The principal axes is defined in characters 3:48 of the 5th line
        exponent = 10.**exponent
        axes.t_axis = {
            'eigenvalue': exponent * float(ndk_string[0:8]),
            'plunge': float(ndk_string[8:11]),
            'azimuth': float(ndk_string[11:15])
        }

        axes.b_axis = {
            'eigenvalue': exponent * float(ndk_string[15:23]),
            'plunge': float(ndk_string[23:26]),
            'azimuth': float(ndk_string[26:30])
        }

        axes.p_axis = {
            'eigenvalue': exponent * float(ndk_string[30:38]),
            'plunge': float(ndk_string[38:41]),
            'azimuth': float(ndk_string[41:])
        }
        return axes

    def _get_nodal_planes_from_ndk_string(self, ndk_string):
        """
        Reads the nodal plane information (represented by 5th line [57:] of the
        tensor representation) and returns an instance of the GCMTNodalPlanes
        class
        """
        planes = GCMTNodalPlanes()
        planes.nodal_plane_1 = {
            'strike': float(ndk_string[0:3]),
            'dip': float(ndk_string[3:6]),
            'rake': float(ndk_string[6:11])
        }
        planes.nodal_plane_2 = {
            'strike': float(ndk_string[11:15]),
            'dip': float(ndk_string[15:18]),
            'rake': float(ndk_string[18:])
        }
        return planes

    def _get_moment_from_ndk_string(self, ndk_string, exponent):
        """
        Returns the moment and the moment magnitude
        """
        moment = float(ndk_string[49:56]) * (10.**exponent)
        version = ndk_string[:3]
        magnitude = utils.moment_magnitude_scalar(moment)
        return moment, version, magnitude
Example #4
0
 def _setup_catalogue(self):
     """
     """
     return GCMTCatalogue()
Example #5
0
class ParseNDKtoGCMT(object):
    """
    Implements the parser to read a file in ndk format to the GCMT catalogue
    """
    def __init__(self, filename):
        """
        :param str filename:
            Name of the catalogue file in ndk format
        """
        self.filename = filename
        self.catalogue = GCMTCatalogue()

    def read_file(self, start_year=None, end_year=None, use_centroid=None):
        """
        Reads the file
        """
        raw_data = getlines(self.filename)
        num_lines = len(raw_data)
        if ((float(num_lines) / 5.) - float(num_lines / 5)) > 1E-9:
            raise IOError('GCMT represented by 5 lines - number in file not'
                          ' a multiple of 5!')
        self.catalogue.number_gcmts = num_lines / 5
        self.catalogue.gcmts = [None] * self.catalogue.number_gcmts #Pre-allocates list
        id0 = 0
        print 'Parsing catalogue ...'
        for iloc in range(0, self.catalogue.number_gcmts):
            self.catalogue.gcmts[iloc] = self.read_ndk_event(raw_data, id0)
            id0 += 5
        print 'complete. Contains %s moment tensors' \
            % self.catalogue.get_number_tensors()
        if not start_year:
            min_years = []
            min_years = [cent.centroid.date.year for cent in self.catalogue.gcmts]
            self.catalogue.start_year = np.min(min_years)

        if not end_year:
            max_years = []
            max_years = [cent.centroid.date.year for cent in self.catalogue.gcmts]
            self.catalogue.end_year = np.max(max_years)
        self.to_hmtk(use_centroid)
        return self.catalogue

    def read_ndk_event(self, raw_data, id0):
        """
        Reads a 5-line batch of data into a set of GCMTs
        """
        gcmt = GCMTEvent()
        # Get hypocentre
        ndkstring = raw_data[id0].rstrip('\n')
        gcmt.hypocentre = self._read_hypocentre_from_ndk_string(ndkstring)
        
        # GCMT metadata
        ndkstring = raw_data[id0 + 1].rstrip('\n')
        gcmt = self._get_metadata_from_ndk_string(gcmt, ndkstring)
        
        # Get Centroid
        ndkstring = raw_data[id0 + 2].rstrip('\n')
        gcmt.centroid = self._read_centroid_from_ndk_string(ndkstring, 
                                                             gcmt.hypocentre)

        # Get Moment Tensor
        ndkstring = raw_data[id0 + 3].rstrip('\n')
        gcmt.moment_tensor = self._get_moment_tensor_from_ndk_string(ndkstring)
        
        # Get principal axes
        ndkstring = raw_data[id0 + 4].rstrip('\n')
        gcmt.principal_axes = self._get_principal_axes_from_ndk_string(
            ndkstring[3:48],
            exponent=gcmt.moment_tensor.exponent)
        
        # Get Nodal Planes
        gcmt.nodal_planes = self._get_nodal_planes_from_ndk_string(
            ndkstring[57:])
        
        # Get Moment and Magnitude
        gcmt.moment, gcmt.version, gcmt.magnitude = \
            self._get_moment_from_ndk_string(ndkstring, 
                                             gcmt.moment_tensor.exponent)
        
        return gcmt

    def to_hmtk(self, use_centroid=True):
        '''
        Convert the content of the GCMT catalogue to a HMTK 
        catalogue. 
        '''
        
        self._preallocate_data_dict()
        for iloc, gcmt in enumerate(self.catalogue.gcmts):
            self.catalogue.data['eventID'][iloc] = iloc

            if use_centroid:
                self.catalogue.data['year'][iloc] = \
                    gcmt.centroid.date.year
                self.catalogue.data['month'][iloc] = \
                    gcmt.centroid.date.month
                self.catalogue.data['day'][iloc] = \
                    gcmt.centroid.date.day
                self.catalogue.data['hour'][iloc] = \
                    gcmt.centroid.time.hour
                self.catalogue.data['minute'][iloc] = \
                    gcmt.centroid.time.minute
                self.catalogue.data['second'][iloc] = \
                    gcmt.centroid.time.second
                self.catalogue.data['longitude'][iloc] = \
                    gcmt.centroid.longitude
                self.catalogue.data['latitude'][iloc] = \
                    gcmt.centroid.latitude
                self.catalogue.data['depth'][iloc] = \
                    gcmt.centroid.depth
            else:
                self.catalogue.data['year'][iloc] = \
                    gcmt.hypocentre.date.year
                self.catalogue.data['month'][iloc] = \
                    gcmt.hypocentre.date.month
                self.catalogue.data['day'][iloc] = \
                    gcmt.hypocentre.date.day
                self.catalogue.data['hour'][iloc] = \
                    gcmt.hypocentre.time.hour
                self.catalogue.data['minute'][iloc] = \
                    gcmt.hypocentre.time.minute
                self.catalogue.data['second'][iloc] = \
                    gcmt.hypocentre.time.second
                self.catalogue.data['longitude'][iloc] = \
                    gcmt.hypocentre.longitude
                self.catalogue.data['latitude'][iloc] = \
                    gcmt.hypocentre.latitude
                self.catalogue.data['depth'][iloc] = \
                    gcmt.hypocentre.depth
            # Moment, magnitude and relative errors
            self.catalogue.data['moment'][iloc] = gcmt.moment
            self.catalogue.data['magnitude'][iloc] = gcmt.magnitude
            self.catalogue.data['f_clvd'][iloc] = gcmt.f_clvd
            self.catalogue.data['e_rel'][iloc] = gcmt.e_rel
            self.catalogue.data['centroidID'][iloc] = gcmt.identifier
            # Nodal planes
            self.catalogue.data['strike1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['strike']
            self.catalogue.data['dip1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['dip']
            self.catalogue.data['rake1'][iloc] = \
                gcmt.nodal_planes.nodal_plane_1['rake']
            self.catalogue.data['strike2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['strike']
            self.catalogue.data['dip2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['dip']
            self.catalogue.data['rake2'][iloc] = \
                gcmt.nodal_planes.nodal_plane_2['rake']
             # Principal axes
            self.catalogue.data['eigenvalue_b'][iloc] = \
                gcmt.principal_axes.b_axis['eigenvalue']
            self.catalogue.data['azimuth_b'][iloc] = \
                gcmt.principal_axes.b_axis['azimuth']
            self.catalogue.data['plunge_b'][iloc] = \
                gcmt.principal_axes.b_axis['plunge']
            self.catalogue.data['eigenvalue_p'][iloc] = \
                gcmt.principal_axes.p_axis['eigenvalue']
            self.catalogue.data['azimuth_p'][iloc] = \
                gcmt.principal_axes.p_axis['azimuth']
            self.catalogue.data['plunge_p'][iloc] = \
                gcmt.principal_axes.p_axis['plunge']
            self.catalogue.data['eigenvalue_t'][iloc] = \
                gcmt.principal_axes.t_axis['eigenvalue']
            self.catalogue.data['azimuth_t'][iloc] = \
                gcmt.principal_axes.t_axis['azimuth']
            self.catalogue.data['plunge_t'][iloc] = \
                gcmt.principal_axes.t_axis['plunge']
        return self.catalogue


    def _preallocate_data_dict(self):
        """
        """
        nvals = self.catalogue.get_number_tensors()
        for key in self.catalogue.TOTAL_ATTRIBUTE_LIST:
            if key in self.catalogue.STRING_ATTRIBUTE_LIST:
                self.catalogue.data[key] = [None for i in range(0, nvals)]
            elif key in self.catalogue.INT_ATTRIBUTE_LIST:
                self.catalogue.data[key] = np.zeros(nvals, dtype=int)
            else:
                self.catalogue.data[key] = np.zeros(nvals, dtype=float)


    def _read_hypocentre_from_ndk_string(self, linestring):
        """
        Reads the hypocentre data from the ndk string to return an
        instance of the GCMTHypocentre class
        """
        hypo = GCMTHypocentre()
        hypo.source = linestring[0:4]
        hypo.date = _read_date_from_string(linestring[5:15])
        hypo.time = _read_time_from_string(linestring[16:26])
        hypo.latitude = float(linestring[27:33])
        hypo.longitude = float(linestring[34:41])
        hypo.depth = float(linestring[42:47])
        magnitudes = map(float, (linestring[48:55]).split(' '))
        if magnitudes[0] > 0.:
            hypo.m_b = magnitudes[0]
        if magnitudes[1] > 0.:
            hypo.m_s = magnitudes[1]
        hypo.location = linestring[56:]
        return hypo


    def _get_metadata_from_ndk_string(self, gcmt, ndk_string):
        """
        Reads the GCMT metadata from line 2 of the ndk batch
        """
        gcmt.identifier = ndk_string[:16]
        inversion_data = re.split('[A-Z:]+', ndk_string[17:61])
        gcmt.metadata['BODY'] = map(float, inversion_data[1].split())
        gcmt.metadata['SURFACE'] = map(float, inversion_data[2].split())
        gcmt.metadata['MANTLE'] = map(float, inversion_data[3].split())
        further_meta = re.split('[: ]+', ndk_string[62:])
        gcmt.metadata['CMT'] = int(further_meta[1])
        gcmt.metadata['FUNCTION'] = {'TYPE': further_meta[2],
                                     'DURATION': float(further_meta[3])}
        return gcmt


    def _read_centroid_from_ndk_string(self, ndk_string, hypocentre):
        """
        Reads the centroid data from the ndk string to return an
        instance of the GCMTCentroid class
        :param str ndk_string:
            String of data (line 3 of ndk format)
        :param hypocentre:
            Instance of the GCMTHypocentre class
        """
        centroid = GCMTCentroid(hypocentre.date,
                                hypocentre.time)

        data = ndk_string[:58].split()
        centroid.centroid_type = data[0].rstrip(':')
        data = map(float, data[1:])
        time_diff = data[0]
        if fabs(time_diff) > 1E-6:
            centroid._get_centroid_time(time_diff)
        centroid.time_error = data[1]
        centroid.latitude = data[2]
        centroid.latitude_error = data[3]
        centroid.longitude = data[4]
        centroid.longitude_error = data[5]
        centroid.depth = data[6]
        centroid.depth_error = data[7]
        centroid.depth_type = ndk_string[59:63]
        centroid.centroid_id = ndk_string[64:]
        return centroid

    def _get_moment_tensor_from_ndk_string(self, ndk_string):
        """
        Reads the moment tensor from the ndk_string and returns an instance of
        the GCMTMomentTensor class.
        By default the ndk format uses the Up, South, East (USE) reference 
        system.
        """
        moment_tensor = GCMTMomentTensor('USE')
        tensor_data = _read_moment_tensor_from_ndk_string(ndk_string, 'USE')
        moment_tensor.tensor = tensor_data[0]
        moment_tensor.tensor_sigma = tensor_data[1]
        moment_tensor.exponent = tensor_data[2]
        return moment_tensor


    def _get_principal_axes_from_ndk_string(self, ndk_string, exponent):
        """
        Gets the principal axes from the ndk string and returns an instance
        of the GCMTPrincipalAxes class
        """
        axes = GCMTPrincipalAxes()
        # The principal axes is defined in characters 3:48 of the 5th line
        exponent = 10. ** exponent
        axes.t_axis = {'eigenvalue': exponent * float(ndk_string[0:8]),
                      'plunge': float(ndk_string[8:11]),
                      'azimuth': float(ndk_string[11:15])}

        axes.b_axis = {'eigenvalue': exponent * float(ndk_string[15:23]),
                       'plunge': float(ndk_string[23:26]),
                       'azimuth': float(ndk_string[26:30])}
        
        axes.p_axis = {'eigenvalue': exponent * float(ndk_string[30:38]),
                       'plunge': float(ndk_string[38:41]),
                       'azimuth': float(ndk_string[41:])}
        return axes

    def _get_nodal_planes_from_ndk_string(self, ndk_string):
        """
        Reads the nodal plane information (represented by 5th line [57:] of the
        tensor representation) and returns an instance of the GCMTNodalPlanes
        class
        """
        planes = GCMTNodalPlanes()
        planes.nodal_plane_1 = {'strike': float(ndk_string[0:3]) ,
                              'dip': float(ndk_string[3:6]),
                              'rake': float(ndk_string[6:11])}
        planes.nodal_plane_2 = {'strike': float(ndk_string[11:15]) ,
                              'dip': float(ndk_string[15:18]),
                              'rake': float(ndk_string[18:])}
        return planes

    def _get_moment_from_ndk_string(self, ndk_string, exponent):
        """
        Returns the moment and the moment magnitude
        """
        moment = float(ndk_string[49:56]) * (10. ** exponent)
        version = ndk_string[:3]
        magnitude = utils.moment_magnitude_scalar(moment)
        return moment, version, magnitude