示例#1
0
    def __init__(self,
                 z_object=None,
                 z_array=None,
                 z_err_array=None,
                 freq=None,
                 rot_z=0):

        #--> read in z_object
        if z_object is not None:
            if z_object.freq == None:
                raise AttributeError('z_object needs to have attrtibute'+\
                                     'freq filled')

            #--> make the z_object an attribute
            self._Z = z_object

        #--> if an array is input read it in and make it a z_object
        if z_array is not None:
            if freq is None:
                raise IOError('freq needs to be input')

            self._Z = mtz.Z(z_array, z_err_array)

            assert len(freq)==len(self._Z.z), \
                    'length of freq is not the same as z'

            self._Z.freq = freq

        #--> rotate data if desired
        self.rotate(rot_z)

        # compute the invariants
        self.compute_invariants()
示例#2
0
文件: mt_old.py 项目: zy911k24/mtpy
    def __init__(self, fn=None, **kwargs):

        self._fn = fn
        self.station = kwargs.pop('station', None)
        self._lat = kwargs.pop('lat', None)
        self._lon = kwargs.pop('lon', None)
        self._elev = kwargs.pop('elev', None)
        self._Z = kwargs.pop('Z', MTz.Z())
        self._Tipper = kwargs.pop('Tipper', MTz.Tipper())
        self._utm_zone = kwargs.pop('utm_zone', None)
        self._east = kwargs.pop('east', None)
        self._north = kwargs.pop('north', None)
        self._rotation_angle = kwargs.pop('rotation_angle', 0)

        self.edi_object = MTedi.Edi()
        self.pt = None
        self.zinv = None
        self._utm_ellipsoid = 23

        #provide key words to fill values if an edi file does not exist
        for key in kwargs.keys():
            setattr(self, key, kwargs[key])

        #--> read in the file name given
        if self._fn is not None:
            self._set_fn(fn)
示例#3
0
文件: distortion.py 项目: Dengg/mtpy
def remove_distortion(z_array=None, z_object=None):

    if z_array is not None:
        z_obj = MTz.Z(z_array=z_array)
    
    elif z_object is not None:
        z_obj = z_object

    #0. generate a Z object
    #1. find distortion via function above, 
    #2. remove distortion via method of z object

    dis, diserr = find_distortion(z_obj)

    try:
        distortion_tensor, zd, zd_err = z_obj.no_distortion(dis, 
                                                distortion_err_tensor=diserr)
        distortion_z_obj = z_obj
        distortion_z_obj.z = zd
        distortion_z_obj.zerr = zd_err 

        return distortion_tensor, distortion_z_obj
        
    except MTex.MTpyError_Z:
        print 'Could not compute distortion tensor'
        
        return np.identity(2), z_obj
示例#4
0
文件: zmm.py 项目: zy911k24/mtpy
    def __init__(self, z_fn=None, **kwargs):

        #        EgbertHeader.__init__(self, **kwargs)
        super(ZMM, self).__init__()

        self.z_fn = z_fn
        self._header_count = 0
        self.Z = mtz.Z()
        self.Tipper = mtz.Tipper()
        self.transfer_functions = None
        self.sigma_e = None
        self.sigma_s = None
        self.period = None

        for key in list(kwargs.keys()):
            setattr(self, key, kwargs[key])
dfn = r"c:\Users\jpeacock\Documents\MountainPass\modem_inv\inv_08\mp_modem_data_z03_t05_topo.dat"
mfn = r"c:\Users\jpeacock\Documents\MountainPass\modem_inv\inv_08\mp_sm02_topo.rho"
occam1d_path = r"c:\MinGW32-xy\Peacock\occam\occam1d.exe"
sv_dir = os.path.dirname(dfn)
# =============================================================================
# read in data file and get mean and median of determinant
# =============================================================================
d_obj = modem.Data()
d_obj.read_data_file(dfn)

rho = np.zeros((d_obj.data_array.shape[0], d_obj.period_list.shape[0]))
phase = np.zeros_like(rho)

for ii, d_arr in enumerate(d_obj.data_array):
    z_obj = mtz.Z(d_arr['z'], freq=1. / d_obj.period_list)
    rho[ii, :] = z_obj.res_det
    phase[ii, :] = z_obj.phase_det

#mean_rho = np.apply_along_axis(lambda x: x[np.nonzero(x)].mean(), 0, rho)
median_rho = np.apply_along_axis(lambda x: np.median(x[np.nonzero(x)]), 0, rho)
median_rho[0] = 0
#mean_phase = np.apply_along_axis(lambda x: x[np.nonzero(x)].mean(), 0, phase)
median_phase = np.apply_along_axis(lambda x: np.median(x[np.nonzero(x)]), 0,
                                   phase)
median_phase[0] = 0
# make occam data file
ocd = occam1d.Data()
rp_tuple = (1. / d_obj.period_list, median_rho, median_rho * .05, median_phase,
            median_phase * .05)
ocd.save_path = sv_dir
示例#6
0
文件: mt.py 项目: schoolhui/mtpy
    def interpolate(self, new_freq_array):
        """
        interpolate the impedance tensor onto different frequencies.
        
        **Arguments**
        
            *new_freq_array* : np.ndarray 
                               a 1-d array of frequencies to interpolate on
                               to.  Must be with in the bounds of the existing
                               frequency range, anything outside and an error
                               will occur.
                               
        **Returns** :
            *new_z_object* : mtpy.core.z.Z object
                             a new impedance object with the corresponding
                             frequencies and components.
                             
            *new_tipper_object* : mtpy.core.z.Tipper object
                             a new tipper object with the corresponding
                             frequencies and components.
                             
        
        :Example: ::
            >>> # make a new edi file for interpolated frequencies 
            >>> import mtpy.core.mt as mt
            >>> edi_fn = r"/home/edi_files/mt_01.edi"
            >>> mt_obj = mt.MT(edi_fn)
            >>> # create a new frequency range to interpolate onto
            >>> new_freq = np.logspace(-3, 3, 24)
            >>> new_z_object, new_tipper_obj = mt_obj.interpolate(new_freq)
            >>> mt_obj.write_edi_file(new_fn=r"/home/edi_files/mt_01_interp.edi",
            >>>                       new_Z=new_z_object,
            >>>                       new_Tipper=new_tipper_object)
            
        """
        # if the interpolation module has not been loaded return
        if interp_import is False:
            print('could not interpolate, need to install scipy')            
            return
        
        #make sure the input is a numpy array
        if type(new_freq_array) != np.ndarray:
            new_freq_array = np.array(new_freq_array)

        # check the bounds of the new frequency array
        if self.Z.freq.min() > new_freq_array.min():
            raise ValueError('New frequency minimum of {0:.5g}'.format(new_freq_array.min())+\
                             ' is smaller than old frequency minimum of {0:.5g}'.format(self.Z.freq.min())+\
                             '.  The new frequency range needs to be within the '+\
                             'bounds of the old one.')
        if self.Z.freq.max() < new_freq_array.max():
            raise ValueError('New frequency maximum of {0:.5g}'.format(new_freq_array.max())+\
                             'is smaller than old frequency maximum of {0:.5g}'.format(self.Z.freq.max())+\
                             '.  The new frequency range needs to be within the '+\
                             'bounds of the old one.')

        # make a new Z object
        new_Z = MTz.Z(z_array=np.zeros((new_freq_array.shape[0], 2, 2), 
                                       dtype='complex'),
                      zerr_array=np.zeros((new_freq_array.shape[0], 2, 2)), 
                      freq=new_freq_array)
                      
        new_Tipper = MTz.Tipper(tipper_array=np.zeros((new_freq_array.shape[0], 1, 2), 
                                             dtype='complex'),
                      tippererr_array=np.zeros((new_freq_array.shape[0], 1, 2)), 
                      freq=new_freq_array)
        
        # interpolate the impedance tensor
        for ii in range(2):
            for jj in range(2):
                z_func_real = spi.interp1d(self.Z.freq, self.Z.z[:, ii, jj].real,
                                           kind='slinear')
                z_func_imag = spi.interp1d(self.Z.freq, self.Z.z[:, ii, jj].imag,
                                           kind='slinear')
                new_Z.z[:, ii, jj] = z_func_real(new_freq_array)+\
                                     1j*z_func_imag(new_freq_array)
                
                z_func_err = spi.interp1d(self.Z.freq, self.Z.zerr[:, ii, jj],
                                           kind='slinear')
                new_Z.zerr[:, ii, jj] = z_func_err(new_freq_array)
                
        # if there is not tipper than skip
        if self.Tipper.tipper is None:
            return new_Z, None
            
        # interpolate the Tipper    
        for jj in range(2):
            t_func_real = spi.interp1d(self.Z.freq, 
                                       self.Tipper.tipper[:, 0, jj].real,
                                       kind='slinear')
            t_func_imag = spi.interp1d(self.Z.freq, 
                                       self.Tipper.tipper[:, 0, jj].imag,
                                       kind='slinear')
            new_Tipper.tipper[:, 0, jj] = t_func_real(new_freq_array)+\
                                          1j*t_func_imag(new_freq_array)
            
            t_func_err = spi.interp1d(self.Z.freq, 
                                      self.Tipper.tippererr[:, 0, jj],
                                       kind='slinear')
            new_Tipper.tippererr[:, 0, jj] = t_func_err(new_freq_array)
        
        return new_Z, new_Tipper
示例#7
0
文件: mt.py 项目: schoolhui/mtpy
    def __init__(self, fn=None, **kwargs):
        
        self._fn = fn
        self.station = kwargs.pop('station', None)
        self._lat = kwargs.pop('lat', None)
        self._lon = kwargs.pop('lon', None)
        self._elev = kwargs.pop('elev', None)
        self._Z = kwargs.pop('Z', MTz.Z())
        self._Tipper = kwargs.pop('Tipper', MTz.Tipper())
        self._utm_zone = kwargs.pop('utm_zone', None)
        self._east = kwargs.pop('east', None)
        self._north = kwargs.pop('north', None)
        self._rotation_angle = kwargs.pop('rotation_angle', 0)
        self._data_type = kwargs.pop('data_type', 'z')
        
        #provide key words to fill values if an edi file does not exist
        if 'z_object' in kwargs:
            self._Z = kwargs['z_object']
            
        if 'z_array' in kwargs:
            self._Z.z = kwargs['z_array']
        
        if 'zerr_array' in kwargs:
            self._Z.zerr = kwargs['zerr_array']
        
        if 'freq' in kwargs:
            self._Z.freq = kwargs['freq']
            self._Tipper.freq = kwargs['freq']
            
        if 'tipper_object' in kwargs:
            self._Tipper = kwargs['tipper_object']
            
        if 'tipper' in kwargs:
            self._Tipper.tipper = kwargs['tipper']
        
        if 'tippererr' in kwargs:
            self._Tipper.tippererr = kwargs['tippererr']
            
        if 'resisitivity' in kwargs:
            self._Z.resistivity = kwargs['resistivity']
        
        if 'resisitivity_err' in kwargs:
            self._Z.resistivity_err = kwargs['resistivity_err']
        
        if 'phase' in kwargs:
            self._Z.phase = kwargs['phase']
            
        if 'phase_err' in kwargs:
            self._Z.phase = kwargs['phase_err']
        
        
        self.edi_object = MTedi.Edi()
        self.pt = None
        self.zinv = None
        self._utm_ellipsoid = 23

        #--> read in the edi file if its given
        if self._fn is not None:
            if self._fn[-3:] == 'edi':
                self._read_edi_file()
            else:
                not_fn = self._fn[os.path.basename(self._fn).find['.']:]
                raise MTex.MTpyError_file_handling('File '+\
                          'type {0} not supported yet.'.format(not_fn))
示例#8
0
def find_distortion(z_object, g='det', num_freq=None, lo_dims=None):
    """
    find optimal distortion tensor from z object

    automatically determine the dimensionality over all frequencies, then find
    the appropriate distortion tensor D
    
    Parameters
    ----------
    
        **z_object** : mtpy.core.z object
                       
        **g** : [ 'det' | '01' | '10 ]
                type of distortion correction
                *default* is 'det'
                
        **num_freq** : int
                       number of frequencies to look for distortion from 
                       the index 0
                       *default* is None, meaning all frequencies are used
                       
        **lo_dims** : list
                      list of dimensions for each frequency
                      *default* is None, meaning calculated from data
                      
    Returns
    -------
    
        **distortion** : np.ndarray(2, 2)
                         distortion array all real values
        
        **distortion_err** : np.ndarray(2, 2)
                             distortion error array


    Examples
    --------

        :Estimate Distortion: ::
        
            >>> import mtpy.analysis.distortion as distortion
            >>> dis, dis_err = distortion.find_distortion(z_obj, num_freq=12)
            
    """

    if num_freq is not None:
        if num_freq > z_object.freq.size:
            num_freq = z_object.freq.size
            print('Number of frequencies to sweep over is too high for z')
            print('setting num_freq to {0}'.format(num_freq))
    else:
        num_freq = z_object.freq.size

    z_obj = MTz.Z(z_object.z[0:num_freq], z_object.z_err[0:num_freq],
                  z_object.freq[0:num_freq])

    g = 'det'

    dim_arr = MTge.dimensionality(z_object=z_obj)
    st_arr = -1 * MTge.strike_angle(z_object=z_obj)[:, 0]

    dis = np.zeros_like(z_obj.z, dtype=np.float)
    dis_err = np.ones_like(z_obj.z, dtype=np.float)

    #dictionary of values that should be no distortion in case distortion
    #cannot be calculated for that component
    rot_mat = np.matrix([[0, -1], [1, 0]])
    for idx, dim in enumerate(dim_arr):
        if np.any(z_obj.z[idx] == 0.0 + 0.0j) == True:
            dis[idx] = np.identity(2)
            print('Found a zero in z at {0}, skipping'.format(idx))
            continue

        if dim == 1:

            if g in ['01', '10']:
                gr = np.abs(z_obj.z.real[idx, int(g[0]), int(g[1])])
                gi = np.abs(z_obj.z.imag[idx, int(g[0]), int(g[1])])
            else:
                gr = np.sqrt(np.linalg.det(z_obj.z.real[idx]))
                gi = np.sqrt(np.linalg.det(z_obj.z.imag[idx]))

            dis[idx] = np.mean(np.array([
                (1. / gr * np.dot(z_obj.z.real[idx], rot_mat)),
                (1. / gi * np.dot(z_obj.z.imag[idx], rot_mat))
            ]),
                               axis=0)

            if z_obj.z_err is not None:
                # find errors of entries for calculating weights

                gr_err = 1. / gr * np.abs(z_obj.z_err[idx])
                gr_err[np.where(gr_err == 0.0)] = 1.0

                gi_err = 1. / gi * np.abs(z_obj.z_err[idx])
                gi_err[np.where(gi_err == 0.0)] = 1.0

                dis_err[idx] = np.mean(np.array([gi_err, gr_err]), axis=0)

        elif dim == 2:
            P = 1
            strike_ang = st_arr[idx]
            if np.isnan(strike_ang):
                strike_ang = 0.0

            if z_obj.z_err is not None:
                err_arr = z_obj.z_err[idx]
                err_arr[np.where(err_arr == 0.0)] = 1.0
            else:
                err_arr = None

            tetm_arr, tetm_err = MTcc.rotatematrix_incl_errors(
                z_obj.z[idx], strike_ang, inmatrix_err=err_arr)

            tetm_r = tetm_arr.real
            tetm_i = tetm_arr.imag
            t_arr_r = -4 * P * tetm_r[0, 1] * tetm_r[1,
                                                     0] / np.linalg.det(tetm_r)
            t_arr_i = -4 * P * tetm_i[0, 1] * tetm_i[1,
                                                     0] / np.linalg.det(tetm_i)

            try:
                T = np.sqrt(max([t_arr_r, t_arr_i])) + .001
            except ValueError:
                T = 2

            sr = np.sqrt(T**2 + 4 * P * tetm_r[0, 1] * tetm_r[1, 0] /
                         np.linalg.det(tetm_r))
            si = np.sqrt(T**2 + 4 * P * tetm_i[0, 1] * tetm_i[1, 0] /
                         np.linalg.det(tetm_i))

            par_r = 2 * tetm_r[0, 1] / (T - sr)
            orth_r = 2 * tetm_r[1, 0] / (T + sr)
            par_i = 2 * tetm_i[0, 1] / (T - si)
            orth_i = 2 * tetm_i[1, 0] / (T + si)

            mat2_r = np.matrix([[0, 1. / orth_r], [1. / par_r, 0]])
            mat2_i = np.matrix([[0, 1. / orth_i], [1. / par_i, 0]])

            avg_mat = np.mean(np.array(
                [np.dot(tetm_r, mat2_r),
                 np.dot(tetm_i, mat2_i)]),
                              axis=0)

            dis[idx] = avg_mat

            if err_arr is not None:
                # find errors of entries for calculating weights
                sigma_sr = np.sqrt((-(2 * P * tetm_r[0, 1] * tetm_r[1, 0] * \
                                      tetm_r[1, 1] * err_arr[0, 0]) / \
                                    (np.linalg.det(tetm_r) ** 2 * sr)) ** 2 + \
                                   ((2 * P * tetm_r[0, 0] * tetm_r[1, 0] *
                                     tetm_r[1, 1] * err_arr[0, 1]) /
                                    (np.linalg.det(tetm_r) ** 2 * sr)) ** 2 + \
                                   ((2 * P * tetm_r[0, 0] * tetm_r[0, 1] *
                                     tetm_r[1, 1] * err_arr[1, 0]) / \
                                    (np.linalg.det(tetm_r) ** 2 * sr)) ** 2 + \
                                   (-(2 * P * tetm_r[0, 1] * tetm_r[1, 0] * \
                                      tetm_r[0, 0] * err_arr[1, 1]) / \
                                    (np.linalg.det(tetm_r) ** 2 * sr)) ** 2)

                sigma_dr_11 = 0.5 * sigma_sr
                sigma_dr_22 = 0.5 * sigma_sr

                sigma_dr_12 = np.sqrt((mat2_r[0, 1] / tetm_r[0, 0] * err_arr[0, 0]) ** 2 + \
                                      (mat2_r[0, 1] / tetm_r[1, 0] * err_arr[1, 0]) ** 2 + \
                                      (0.5 * tetm_r[0, 0] / tetm_r[1, 0] * sigma_sr) ** 2)
                sigma_dr_21 = np.sqrt((mat2_r[1, 0] / tetm_r[1, 1] * err_arr[1, 1]) ** 2 + \
                                      (mat2_r[1, 0] / tetm_r[0, 1] * err_arr[0, 1]) ** 2 + \
                                      (0.5 * tetm_r[1, 1] / tetm_r[0, 1] * sigma_sr) ** 2)

                dis_err_r = np.array([[sigma_dr_11, sigma_dr_12],
                                      [sigma_dr_21, sigma_dr_22]])

                sigma_si = np.sqrt((-(2 * P * tetm_i[0, 1] * tetm_i[1, 0] * \
                                      tetm_i[1, 1] * err_arr[0, 0]) / \
                                    (np.linalg.det(tetm_i) ** 2 * sr)) ** 2 + \
                                   ((2 * P * tetm_i[0, 0] * tetm_i[1, 0] * \
                                     tetm_i[1, 1] * err_arr[0, 1]) / \
                                    (np.linalg.det(tetm_i) ** 2 * sr)) ** 2 + \
                                   ((2 * P * tetm_i[0, 0] * tetm_i[0, 1] * \
                                     tetm_i[1, 1] * err_arr[1, 0]) / \
                                    (np.linalg.det(tetm_i) ** 2 * sr)) ** 2 + \
                                   (-(2 * P * tetm_i[0, 1] * tetm_i[1, 0] * \
                                      tetm_i[0, 0] * err_arr[1, 1]) / \
                                    (np.linalg.det(tetm_i) ** 2 * sr)) ** 2)

                sigma_di_11 = 0.5 * sigma_si
                sigma_di_22 = 0.5 * sigma_si
                sigma_di_12 = np.sqrt((mat2_i[0, 1] / tetm_i[0, 0] * err_arr[0, 0]) ** 2 + \
                                      (mat2_i[0, 1] / tetm_i[1, 0] * err_arr[1, 0]) ** 2 + \
                                      (0.5 * tetm_i[0, 0] / tetm_i[1, 0] * sigma_si) ** 2)
                sigma_di_21 = np.sqrt((mat2_i[1, 0] / tetm_i[1, 1] * err_arr[1, 1]) ** 2 + \
                                      (mat2_i[1, 0] / tetm_i[0, 1] * err_arr[0, 1]) ** 2 + \
                                      (0.5 * tetm_i[1, 1] / tetm_i[0, 1] * sigma_si) ** 2)

                dis_err_i = np.array([[sigma_di_11, sigma_di_12],
                                      [sigma_di_21, sigma_di_22]])

                dis_err[idx] = np.mean(np.array([dis_err_r, dis_err_i]))
        else:
            dis[idx] = np.identity(2)

    nonzero_idx = np.array(list(set(np.nonzero(dis)[0])))

    dis_avg, weights_sum = np.average(dis[nonzero_idx],
                                      axis=0,
                                      weights=(1. / dis_err[nonzero_idx])**2,
                                      returned=True)

    dis_avg_err = np.sqrt(1. / weights_sum)

    return dis_avg, dis_avg_err
示例#9
0
    def plot(self):
        """
        plot the data
        """

        if self.station is None:
            return

        s_index = np.where(self.ws_data.data['station'] == self.station)[0][0]

        z_obj = mtz.Z(self.ws_data.data[s_index]['z_data'],
                      self.ws_data.data[s_index]['z_data_err']*\
                        self.ws_data.data[s_index]['z_err_map'],
                      1./self.ws_data.period_list)
        period = self.ws_data.period_list

        # need to make sure that resistivity and phase is computed
        z_obj._compute_res_phase()

        plt.rcParams['font.size'] = self.plot_settings.fs
        fontdict = {'size': self.plot_settings.fs + 2, 'weight': 'bold'}

        #--> make key word dictionaries for plotting
        kw_xx = {
            'color': self.plot_settings.cted,
            'marker': self.plot_settings.mted,
            'ms': self.plot_settings.ms,
            'ls': ':',
            'lw': self.plot_settings.lw,
            'e_capsize': self.plot_settings.e_capsize,
            'e_capthick': self.plot_settings.e_capthick,
            'picker': 3
        }

        kw_yy = {
            'color': self.plot_settings.ctmd,
            'marker': self.plot_settings.mtmd,
            'ms': self.plot_settings.ms,
            'ls': ':',
            'lw': self.plot_settings.lw,
            'e_capsize': self.plot_settings.e_capsize,
            'e_capthick': self.plot_settings.e_capthick,
            'picker': 3
        }

        #convert to apparent resistivity and phase
        if self.plot_z == True:
            scaling = np.zeros_like(z_obj.z)
            for ii in range(2):
                for jj in range(2):
                    scaling[:, ii, jj] = 1. / np.sqrt(z_obj.freq)
            plot_res = abs(z_obj.z.real * scaling)
            plot_res_err = abs(z_obj.z_err * scaling)
            plot_phase = abs(z_obj.z.imag * scaling)
            plot_phase_err = abs(z_obj.z_err * scaling)
            h_ratio = [1, 1]

        elif self.plot_z == False:
            plot_res = z_obj.resistivity
            plot_res_err = z_obj.resistivity_err
            plot_phase = z_obj.phase
            plot_phase_err = z_obj.phase_err
            h_ratio = [2, 1]

        #find locations where points have been masked
        nzxx = np.nonzero(z_obj.z[:, 0, 0])[0]
        nzxy = np.nonzero(z_obj.z[:, 0, 1])[0]
        nzyx = np.nonzero(z_obj.z[:, 1, 0])[0]
        nzyy = np.nonzero(z_obj.z[:, 1, 1])[0]

        self.figure.clf()
        self.figure.suptitle(str(self.station), fontdict=fontdict)

        #set the grid of subplots
        gs = gridspec.GridSpec(2, 4, height_ratios=h_ratio)
        gs.update(wspace=self.plot_settings.subplot_wspace,
                  left=self.plot_settings.subplot_left,
                  top=self.plot_settings.subplot_top,
                  bottom=self.plot_settings.subplot_bottom,
                  right=self.plot_settings.subplot_right,
                  hspace=self.plot_settings.subplot_hspace)

        axrxx = self.figure.add_subplot(gs[0, 0])
        axrxy = self.figure.add_subplot(gs[0, 1], sharex=axrxx)
        axryx = self.figure.add_subplot(gs[0, 2], sharex=axrxx)
        axryy = self.figure.add_subplot(gs[0, 3], sharex=axrxx)

        axpxx = self.figure.add_subplot(gs[1, 0])
        axpxy = self.figure.add_subplot(gs[1, 1], sharex=axrxx)
        axpyx = self.figure.add_subplot(gs[1, 2], sharex=axrxx)
        axpyy = self.figure.add_subplot(gs[1, 3], sharex=axrxx)

        self.ax_list = [axrxx, axrxy, axryx, axryy, axpxx, axpxy, axpyx, axpyy]

        # plot data response
        erxx = mtplottools.plot_errorbar(axrxx, period[nzxx], plot_res[nzxx, 0,
                                                                       0],
                                         plot_res_err[nzxx, 0, 0], **kw_xx)
        erxy = mtplottools.plot_errorbar(axrxy, period[nzxy], plot_res[nzxy, 0,
                                                                       1],
                                         plot_res_err[nzxy, 0, 1], **kw_xx)
        eryx = mtplottools.plot_errorbar(axryx, period[nzyx], plot_res[nzyx, 1,
                                                                       0],
                                         plot_res_err[nzyx, 1, 0], **kw_yy)
        eryy = mtplottools.plot_errorbar(axryy, period[nzyy], plot_res[nzyy, 1,
                                                                       1],
                                         plot_res_err[nzyy, 1, 1], **kw_yy)
        #plot phase
        epxx = mtplottools.plot_errorbar(axpxx, period[nzxx], plot_phase[nzxx,
                                                                         0, 0],
                                         plot_phase_err[nzxx, 0, 0], **kw_xx)
        epxy = mtplottools.plot_errorbar(axpxy, period[nzxy], plot_phase[nzxy,
                                                                         0, 1],
                                         plot_phase_err[nzxy, 0, 1], **kw_xx)
        epyx = mtplottools.plot_errorbar(axpyx, period[nzyx], plot_phase[nzyx,
                                                                         1, 0],
                                         plot_phase_err[nzyx, 1, 0], **kw_yy)
        epyy = mtplottools.plot_errorbar(axpyy, period[nzyy], plot_phase[nzyy,
                                                                         1, 1],
                                         plot_phase_err[nzyy, 1, 1], **kw_yy)

        #----------------------------------------------
        # get error bar list for editing later
        self._err_list = [[erxx[1][0], erxx[1][1], erxx[2][0]],
                          [erxy[1][0], erxy[1][1], erxy[2][0]],
                          [eryx[1][0], eryx[1][1], eryx[2][0]],
                          [eryy[1][0], eryy[1][1], eryy[2][0]]]
        line_list = [[erxx[0]], [erxy[0]], [eryx[0]], [eryy[0]]]

        #------------------------------------------
        # make things look nice
        # set titles of the Z components
        label_list = [['$Z_{xx}$'], ['$Z_{xy}$'], ['$Z_{yx}$'], ['$Z_{yy}$']]
        for ax, label in zip(self.ax_list[0:4], label_list):
            ax.set_title(label[0],
                         fontdict={
                             'size': self.plot_settings.fs + 2,
                             'weight': 'bold'
                         })

        #--> set limits if input
        if self.plot_settings.res_xx_limits is not None:
            axrxx.set_ylim(self.plot_settings.res_xx_limits)
        if self.plot_settings.res_xy_limits is not None:
            axrxy.set_ylim(self.plot_settings.res_xy_limits)
        if self.plot_settings.res_yx_limits is not None:
            axryx.set_ylim(self.plot_settings.res_yx_limits)
        if self.plot_settings.res_yy_limits is not None:
            axryy.set_ylim(self.plot_settings.res_yy_limits)

        if self.plot_settings.phase_xx_limits is not None:
            axpxx.set_ylim(self.plot_settings.phase_xx_limits)
        if self.plot_settings.phase_xy_limits is not None:
            axpxy.set_ylim(self.plot_settings.phase_xy_limits)
        if self.plot_settings.phase_yx_limits is not None:
            axpyx.set_ylim(self.plot_settings.phase_yx_limits)
        if self.plot_settings.phase_yy_limits is not None:
            axpyy.set_ylim(self.plot_settings.phase_yy_limits)

        #set axis properties
        for aa, ax in enumerate(self.ax_list):
            ax.tick_params(axis='y', pad=self.plot_settings.ylabel_pad)
            ylabels = ax.get_yticks().tolist()
            if aa < 4:
                ylabels[-1] = ''
                ylabels[0] = ''
                ax.set_yticklabels(ylabels)
                plt.setp(ax.get_xticklabels(), visible=False)
                if self.plot_z == True:
                    ax.set_yscale('log')

            else:
                ax.set_xlabel('Period (s)', fontdict=fontdict)

            if aa < 4 and self.plot_z is False:
                ax.set_yscale('log')

            #set axes labels
            if aa == 0:
                if self.plot_z == False:
                    ax.set_ylabel('App. Res. ($\mathbf{\Omega \cdot m}$)',
                                  fontdict=fontdict)
                elif self.plot_z == True:
                    ax.set_ylabel('Re[Z (mV/km nT)]', fontdict=fontdict)
            elif aa == 4:
                if self.plot_z == False:
                    ax.set_ylabel('Phase (deg)', fontdict=fontdict)
                elif self.plot_z == True:
                    ax.set_ylabel('Im[Z (mV/km nT)]', fontdict=fontdict)

            ax.set_xscale('log')
            ax.set_xlim(xmin=10**(np.floor(np.log10(period[0]))) * 1.01,
                        xmax=10**(np.ceil(np.log10(period[-1]))) * .99)
            ax.grid(True, alpha=.25)

        ##----------------------------------------------
        #plot model response
        if self.ws_resp is not None:
            s_index = np.where(
                self.ws_resp.resp['station'] == self.station)[0][0]

            resp_z_obj = mtz.Z(self.ws_resp.resp[s_index]['z_resp'], None,
                               1. / self.ws_resp.period_list)

            resp_z_err = np.nan_to_num((z_obj.z - resp_z_obj.z) / z_obj.z_err)
            resp_z_obj._compute_res_phase()

            #convert to apparent resistivity and phase
            if self.plot_z == True:
                scaling = np.zeros_like(resp_z_obj.z)
                for ii in range(2):
                    for jj in range(2):
                        scaling[:, ii, jj] = 1. / np.sqrt(resp_z_obj.freq)
                r_plot_res = abs(resp_z_obj.z.real * scaling)
                r_plot_phase = abs(resp_z_obj.z.imag * scaling)

            elif self.plot_z == False:
                r_plot_res = resp_z_obj.resistivity
                r_plot_phase = resp_z_obj.phase

            rms_xx = resp_z_err[:, 0, 0].std()
            rms_xy = resp_z_err[:, 0, 1].std()
            rms_yx = resp_z_err[:, 1, 0].std()
            rms_yy = resp_z_err[:, 1, 1].std()

            #--> make key word dictionaries for plotting
            kw_xx = {
                'color': self.plot_settings.ctem,
                'marker': self.plot_settings.mtem,
                'ms': self.plot_settings.ms,
                'ls': ':',
                'lw': self.plot_settings.lw,
                'e_capsize': self.plot_settings.e_capsize,
                'e_capthick': self.plot_settings.e_capthick
            }

            kw_yy = {
                'color': self.plot_settings.ctmm,
                'marker': self.plot_settings.mtmm,
                'ms': self.plot_settings.ms,
                'ls': ':',
                'lw': self.plot_settings.lw,
                'e_capsize': self.plot_settings.e_capsize,
                'e_capthick': self.plot_settings.e_capthick
            }

            # plot data response
            rerxx = mtplottools.plot_errorbar(axrxx, period[nzxx],
                                              r_plot_res[nzxx, 0,
                                                         0], None, **kw_xx)
            rerxy = mtplottools.plot_errorbar(axrxy, period[nzxy],
                                              r_plot_res[nzxy, 0,
                                                         1], None, **kw_xx)
            reryx = mtplottools.plot_errorbar(axryx, period[nzyx],
                                              r_plot_res[nzyx, 1,
                                                         0], None, **kw_yy)
            reryy = mtplottools.plot_errorbar(axryy, period[nzyy],
                                              r_plot_res[nzyy, 1,
                                                         1], None, **kw_yy)
            #plot phase
            repxx = mtplottools.plot_errorbar(axpxx, period[nzxx],
                                              r_plot_phase[nzxx, 0,
                                                           0], None, **kw_xx)
            repxy = mtplottools.plot_errorbar(axpxy, period[nzxy],
                                              r_plot_phase[nzxy, 0,
                                                           1], None, **kw_xx)
            repyx = mtplottools.plot_errorbar(axpyx, period[nzyx],
                                              r_plot_phase[nzyx, 1,
                                                           0], None, **kw_yy)
            repyy = mtplottools.plot_errorbar(axpyy, period[nzyy],
                                              r_plot_phase[nzyy, 1,
                                                           1], None, **kw_yy)

            # add labels to legends
            line_list[0] += [rerxx[0]]
            line_list[1] += [rerxy[0]]
            line_list[2] += [reryx[0]]
            line_list[3] += [reryy[0]]
            label_list[0] += ['$Z^m_{xx}$ ' + 'rms={0:.2f}'.format(rms_xx)]
            label_list[1] += ['$Z^m_{xy}$ ' + 'rms={0:.2f}'.format(rms_xy)]
            label_list[2] += ['$Z^m_{yx}$ ' + 'rms={0:.2f}'.format(rms_yx)]
            label_list[3] += ['$Z^m_{yy}$ ' + 'rms={0:.2f}'.format(rms_yy)]

            legend_ax_list = self.ax_list[0:4]
            for aa, ax in enumerate(legend_ax_list):
                ax.legend(
                    line_list[aa],
                    label_list[aa],
                    loc=self.plot_settings.legend_loc,
                    bbox_to_anchor=self.plot_settings.legend_pos,
                    markerscale=self.plot_settings.legend_marker_scale,
                    borderaxespad=self.plot_settings.legend_border_axes_pad,
                    labelspacing=self.plot_settings.legend_label_spacing,
                    handletextpad=self.plot_settings.legend_handle_text_pad,
                    borderpad=self.plot_settings.legend_border_pad,
                    prop={'size': max([self.plot_settings.fs, 5])})

        self.mpl_widget.draw()
示例#10
0
            jj, kk = index_dict[ii]
            try:
                zr, zi = zz.split("+")
                zi = zi.replace("i", "")
            except ValueError:
                zr = zz
                zi = 0
            if ii < 4:
                z[mm, jj, kk] = float(zr) - 1j * float(zi)
            else:
                err[mm, jj, kk] = np.sqrt(np.abs(float(zr) + 1j * float(zi)))

    z[:, 1, 0] *= -1
    z[:, 0, 1] *= 796
    z[:, 1, 0] *= 796

    return z, err


for txt_fn in fn_path.glob("*.txt"):
    # if 's22' not in txt_fn.name:
    #     continue
    zmm_fn = txt_fn.with_suffix(".zmm")
    if zmm_fn.exists():
        m_obj = mt.MT(zmm_fn)
        new_z, new_err = read_txt(txt_fn)
        m_obj.Z = z.Z(new_z, new_err, np.array(f_list))
        m_obj.write_mt_file(fn_basename="{0}_uc".format(m_obj.station))
    else:
        print("ERROR: No zmm file {0}".format(zmm_fn))
示例#11
0
def calculate_depth_nb(z_object = None, z_array = None, periods = None):
    """
    Determine an array of Z_nb (depth dependent Niblett-Bostick transformed Z) 
    from the 1D and 2D parts of an impedance tensor array Z. 
    
    The calculation of the Z_nb needs 6 steps:

	1) Determine the dimensionality of the Z(T), discard all 3D parts
	2) Rotate all Z(T) to TE/TM setup (T_parallel/T_ortho)
	3) Transform every component individually by Niblett-Bostick
	4) collect the respective 2 components each for equal/similar depths
	5) interprete them as TE_nb/TM_nb
	6) set up Z_nb(depth)

    If 1D layers occur inbetween 2D layers, the strike angle is undefined therein.
    We take an - arbitrarily chosen - linear interpolation of strike angle for 
    these layers, with the values varying between the angles of the bounding 
    upper and lower 2D layers (linearly w.r.t. the periods).   

    Use the output for instance for the determination of 
    NB-transformed phase tensors.

    Note:
        No propagation of errors implemented yet!
	
    Arguments
    -------------
        *z_object* : mtpy.core.z object
                    
        *z_array* : np.ndarray [num_periods, 2, 2]
        
        *periods* : np.ndarray(num_periods)
                   only input if input z_array, otherwise periods are extracted
                   from z_object.freq

    Returns
    ------------------
        *depth_array* : np.ndarray(num_periods, 
                                   dtype=['period', 'depth_min', 'depth_max',
                                          'rho_min', 'rho_max'])
                        numpy structured array with keywords.
                            - period    --> period in s
                            - depth_min --> minimum depth estimated (m) 
                            - depth_max --> maximum depth estimated (m) 
                            - rho_min --> minimum resistivity estimated (Ohm-m) 
                            - rho_max --> maximum resistivity estimated (Ohm-m) 

    Example
    ------------
        >>> import mtpy.analysis.niblettbostick as nb
        >>> depth_array = nb.calculate_znb(z_object=z1)
        >>> # plot the results
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(1,1,1)
        >>> ax.semilogy(depth_array['depth_min'], depth_array['period'])
        >>> ax.semilogy(depth_array['depth_max'], depth_array['period'])
        >>> plt.show()

    """


    #deal with inputs
    if z_object is not None:
        z_obj = z_object
        periods = 1./z_object.freq
    else:
        z_obj = MTz.Z(z_array=z_array, freq=1./periods) 
        periods = periods

    dimensions = MTge.dimensionality(z_array=z_obj.z)
    angles = MTge.strike_angle(z_array=z_obj.z)

    #reduce actual Z by the 3D layers:
#    z_2d = z[np.where(dimensions != 3)[0]]
    angles_2d = np.nan_to_num(angles[np.where(dimensions != 3)][:, 0])
    periods_2d = periods[np.where(dimensions != 3)]
    
    # interperpolate strike angle onto all periods
    # make a function for strike using only 2d angles
    strike_interp = spi.interp1d(periods_2d, angles_2d, 
                                 bounds_error=False,
                                 fill_value=0)
    strike_angles = strike_interp(periods)
    
    # rotate z to be along the interpolated strike angles
    z_obj.rotate(strike_angles)
    
#    angles_incl1D = interpolate_strike_angles(angles_2d, periods_2d)
	
#    z3 = MTz.rotate_z(z_2d, -angles_incl1D)[0]

    #at this point we assume that the two modes are the off-diagonal elements!!
    #TE is element (1,2), TM at (2,1)
#    lo_nb_max = []
#    lo_nb_min = []
    
    depth_array = np.zeros(periods.shape[0], 
                           dtype=[('period', np.float),
                                  ('depth_min', np.float),
                                  ('depth_max', np.float),
                                  ('rho_min', np.float),
                                  ('rho_max', np.float)])

##    app_res, app_res_err, phase, phase_err = MTz.z2resphi(z3, periods_2d)
#    app_res, app_res_err, phase, phase_err = MTz.z2resphi(z_rot, periods)

    for ii, per in enumerate(periods):
        te_rho, te_depth = rhophi2rhodepth(z_obj.resistivity[ii, 0, 1], 
                                           z_obj.phase[ii, 0, 1], 
                                           per)
        tm_rho, tm_depth = rhophi2rhodepth(z_obj.resistivity[ii, 1, 0], 
                                           z_obj.phase[ii, 1, 0], 
                                           per)
        depth_array[ii]['period'] = per
        depth_array[ii]['depth_min'] = min([te_depth, tm_depth]) 
        depth_array[ii]['depth_max'] = max([te_depth, tm_depth]) 
        depth_array[ii]['rho_min'] = min([te_rho, tm_rho]) 
        depth_array[ii]['rho_max'] = max([te_rho, tm_rho])
        
    return depth_array
    if f_index == nf:
        data_list.append({
            'name': name,
            'res': res,
            'phase': phase,
            'res_err': res_err,
            'phase_err': phase,
            'tipper': tipper,
            'tipper_err': tipper_err
        })
        print 'Station = {0}, no. freq = {1}'.format(name, nf)

        #write edi file
        data_edi = mtedi.Edi()
        data_z = mtz.Z()
        data_z.freq = frequency
        data_z.set_res_phase(res,
                             phase,
                             reserr_array=res_err,
                             phaseerr_array=phase_err)

        data_T = mtz.Tipper(tipper_array=tipper, tippererr_array=tipper_err)
        data_T.freq = frequency

        data_edi.Z = data_z
        data_edi.Tipper = data_T

        #---------------HEADER----------------------------------------------
        data_edi.head = dict([('dataid', name), ('acqby', 'P. E. Wannamaker'),
                              ('fileby', 'P.E. Wannamaker'),
示例#13
0
文件: jfile.py 项目: zy911k24/mtpy
    def read_j_file(self, j_fn=None):
        """
        read_j_file will read in a *.j file output by BIRRP (better than reading lots of *.<k>r<l>.rf files)
    
        Input:
        j-filename
    
        Output: 4-tuple
        - periods : N-array
        - Z_array : 2-tuple - values and errors
        - tipper_array : 2-tuple - values and errors
        - processing_dict : parsed processing parameters from j-file header
    
        """
        # read data
        z_index_dict = {
            'zxx': (0, 0),
            'zxy': (0, 1),
            'zyx': (1, 0),
            'zyy': (1, 1)
        }
        t_index_dict = {'tzx': (0, 0), 'tzy': (0, 1)}

        if j_fn is not None:
            self.j_fn = j_fn

        print('--> Reading {0}'.format(self.j_fn))

        j_line_list = self._validate_j_file()

        self.read_header(j_lines=j_line_list)
        self.read_metadata(j_lines=j_line_list)

        data_lines = [
            j_line for j_line in j_line_list
            if not '>' in j_line and not '#' in j_line
        ][1:]

        # sometimes birrp outputs some missing periods, so the best way to deal with
        # this that I could come up with was to get things into dictionaries with
        # key words that are the period values, then fill in Z and T from there
        # leaving any missing values as 0

        # make empty dictionary that have keys as the component
        z_dict = dict([(z_key, {}) for z_key in list(z_index_dict.keys())])
        t_dict = dict([(t_key, {}) for t_key in list(t_index_dict.keys())])
        for d_line in data_lines:
            # check to see if we are at the beginning of a component block, if so
            # set the dictionary key to that value
            if 'z' in d_line.lower():
                d_key = d_line.strip().split()[0].lower()
            # if we are at the number of periods line, skip it
            elif len(
                    d_line.strip().split()) == 1 and 'r' not in d_line.lower():
                continue
            elif 'r' in d_line.lower():
                break
            # get the numbers into the correct dictionary with a key as period and
            # for now we will leave the numbers as a list, which we will parse later
            else:
                # split the line up into each number
                d_list = d_line.strip().split()

                # make a copy of the list to be sure we don't rewrite any values,
                # not sure if this is necessary at the moment
                d_value_list = list(d_list)
                for d_index, d_value in enumerate(d_list):
                    # check to see if the column number can be converted into a float
                    # if it can't, then it will be set to 0, which is assumed to be
                    # a masked number when writing to an .edi file

                    try:
                        d_value = float(d_value)
                        # need to check for masked points represented by
                        # birrp as -999, apparently
                        if d_value == -999 or np.isnan(d_value):
                            d_value_list[d_index] = 0.0
                        else:
                            d_value_list[d_index] = d_value
                    except ValueError:
                        d_value_list[d_index] = 0.0

                # put the numbers in the correct dictionary as:
                # key = period, value = [real, imaginary, error]
                if d_key in list(z_index_dict.keys()):
                    z_dict[d_key][d_value_list[0]] = d_value_list[1:4]
                elif d_key in list(t_index_dict.keys()):
                    t_dict[d_key][d_value_list[0]] = d_value_list[1:4]

        # --> now we need to get the set of periods for all components
        # check to see if there is any tipper data output

        all_periods = []
        for z_key in list(z_index_dict.keys()):
            for f_key in list(z_dict[z_key].keys()):
                all_periods.append(f_key)

        if len(list(t_dict['tzx'].keys())) == 0:
            print('Could not find any Tipper data in {0}'.format(self.j_fn))
            find_tipper = False

        else:
            for t_key in list(t_index_dict.keys()):
                for f_key in list(t_dict[t_key].keys()):
                    all_periods.append(f_key)
            find_tipper = True

        all_periods = np.array(sorted(list(set(all_periods))))
        all_periods = all_periods[np.nonzero(all_periods)]
        num_per = len(all_periods)

        # fill arrays using the period key from all_periods
        z_arr = np.zeros((num_per, 2, 2), dtype=np.complex)
        z_err_arr = np.zeros((num_per, 2, 2), dtype=np.float)

        t_arr = np.zeros((num_per, 1, 2), dtype=np.complex)
        t_err_arr = np.zeros((num_per, 1, 2), dtype=np.float)

        for p_index, per in enumerate(all_periods):
            for z_key in sorted(z_index_dict.keys()):
                kk = z_index_dict[z_key][0]
                ll = z_index_dict[z_key][1]
                try:
                    z_value = z_dict[z_key][per][0] + 1j * z_dict[z_key][per][1]
                    z_arr[p_index, kk, ll] = z_value
                    z_err_arr[p_index, kk, ll] = z_dict[z_key][per][2]
                except KeyError:
                    print('No value found for period {0:.4g}'.format(per))
                    print('For component {0}'.format(z_key))
            if find_tipper is True:
                for t_key in sorted(t_index_dict.keys()):
                    kk = t_index_dict[t_key][0]
                    ll = t_index_dict[t_key][1]
                    try:
                        t_value = t_dict[t_key][per][
                            0] + 1j * t_dict[t_key][per][1]
                        t_arr[p_index, kk, ll] = t_value
                        t_err_arr[p_index, kk, ll] = t_dict[t_key][per][2]
                    except KeyError:
                        print('No value found for period {0:.4g}'.format(per))
                        print('For component {0}'.format(t_key))

        # put the results into mtpy objects
        freq = 1. / all_periods
        z_arr[np.where(z_arr == np.inf)] = 0 + 0j
        t_arr[np.where(t_arr == np.inf)] = 0 + 0j
        z_err_arr[np.where(z_err_arr == np.inf)] = 10**6
        t_err_arr[np.where(t_err_arr == np.inf)] = 10**6

        self.Z = mtz.Z(z_arr, z_err_arr, freq)
        self.Tipper = mtz.Tipper(t_arr, t_err_arr, freq)
示例#14
0
文件: zmm.py 项目: zy911k24/mtpy
    def calculate_impedance(self, angle=0.):
        """
        calculate the impedances from the transfer functions
        """

        # check to see if there are actually electric fields in the TFs
        if not hasattr(self, 'ex') or not hasattr(self, 'ey'):
            raise ZMMError("Cannot return apparent resistivity and phase "
                           "data because these TFs do not contain electric "
                           "fields as a predicted channel.")

        # transform the TFs first...
        # build transformation matrix for predictor channels
        #    (horizontal magnetic fields)
        hx_index = self.hx.index
        hy_index = self.hy.index
        u = np.eye(2, 2)
        u[hx_index, hx_index] = np.cos(np.deg2rad(self.hx.azimuth - angle))
        u[hx_index, hy_index] = np.sin(np.deg2rad(self.hx.azimuth - angle))
        u[hy_index, hx_index] = np.cos(np.deg2rad(self.hy.azimuth - angle))
        u[hy_index, hy_index] = np.sin(np.deg2rad(self.hy.azimuth - angle))
        u = np.linalg.inv(u)

        # build transformation matrix for predicted channels (electric fields)
        ex_index = self.ex.index
        ey_index = self.ey.index
        v = np.eye(self.transfer_functions.shape[1],
                   self.transfer_functions.shape[1])
        v[ex_index - 2,
          ex_index - 2] = np.cos(np.deg2rad(self.ex.azimuth - angle))
        v[ey_index - 2,
          ex_index - 2] = np.sin(np.deg2rad(self.ex.azimuth - angle))
        v[ex_index - 2,
          ey_index - 2] = np.cos(np.deg2rad(self.ey.azimuth - angle))
        v[ey_index - 2,
          ey_index - 2] = np.sin(np.deg2rad(self.ey.azimuth - angle))

        # matrix multiplication...
        rotated_transfer_functions = np.matmul(
            v, np.matmul(self.transfer_functions, u.T))
        rotated_sigma_s = np.matmul(u, np.matmul(self.sigma_s, u.T))
        rotated_sigma_e = np.matmul(v, np.matmul(self.sigma_e, v.T))

        # now pull out the impedance tensor
        z = np.zeros((self.num_freq, 2, 2), dtype=np.complex64)
        z[:, 0, 0] = rotated_transfer_functions[:, ex_index - 2,
                                                hx_index]  # Zxx
        z[:, 0, 1] = rotated_transfer_functions[:, ex_index - 2,
                                                hy_index]  # Zxy
        z[:, 1, 0] = rotated_transfer_functions[:, ey_index - 2,
                                                hx_index]  # Zyx
        z[:, 1, 1] = rotated_transfer_functions[:, ey_index - 2,
                                                hy_index]  # Zyy

        # and the variance information
        var = np.zeros((self.num_freq, 2, 2))
        var[:, 0, 0] = np.real(rotated_sigma_e[:, ex_index - 2, ex_index - 2] *
                               rotated_sigma_s[:, hx_index, hx_index])
        var[:, 0, 1] = np.real(rotated_sigma_e[:, ex_index - 2, ex_index - 2] *
                               rotated_sigma_s[:, hy_index, hy_index])
        var[:, 1, 0] = np.real(rotated_sigma_e[:, ey_index - 2, ey_index - 2] *
                               rotated_sigma_s[:, hx_index, hx_index])
        var[:, 1, 1] = np.real(rotated_sigma_e[:, ey_index - 2, ey_index - 2] *
                               rotated_sigma_s[:, hy_index, hy_index])

        error = np.sqrt(var)

        z_object = mtz.Z(z, error, self.frequency)
        return z_object
示例#15
0
import numpy as np
import mtpy.core.z as mtz
import matplotlib.pyplot as plt

dfn = r"c:\Users\jpeacock\OneDrive - DOI\Geothermal\Umatilla\modem_inv\inv_07\um_modem_data_z05.dat"

d_obj = modem.Data()
d_obj.read_data_file(dfn)

rho = np.zeros((d_obj.data_array.shape[0], d_obj.period_list.shape[0]))
# det_z = np.linalg.det(d_obj.data_array['z'])
# mean_z = np.mean(det_z[np.nonzero(det_z)], axis=0)
# mean_rho = (.02/(1/d_obj.period_list))*np.abs(mean_z)

for ii, d_arr in enumerate(d_obj.data_array):
    z_obj = mtz.Z(d_arr["z"], freq=1.0 / d_obj.period_list)
    rho[ii, :] = z_obj.res_det

mean_rho = np.apply_along_axis(lambda x: x[np.nonzero(x)].mean(), 0, rho)
median_rho = np.apply_along_axis(lambda x: np.median(x[np.nonzero(x)]), 0, rho)

fig = plt.figure()

ax = fig.add_subplot(1, 1, 1)
(l1, ) = ax.loglog(d_obj.period_list, mean_rho, lw=2, color=(0.75, 0.25, 0))
(l2, ) = ax.loglog(d_obj.period_list, median_rho, lw=2, color=(0, 0.25, 0.75))

ax.loglog(
    d_obj.period_list,
    np.repeat(mean_rho.mean(), d_obj.period_list.size),
    ls="--",
示例#16
0
            # check for empty values and set them to 0, check for any
            # other characters sometimes there are ****** for a null
            # component
            try:
                d_lines[ii] = float(dd)
                if d_lines[ii] == 1.0e32:
                    d_lines[ii] = 0.0
            except ValueError:
                d_lines[ii] = 0.0
        data_dict[key] += d_lines

## fill useful arrays
freq_arr = np.array(data_dict["freq"], dtype=np.float)

## fill impedance tensor
z_obj = mtz.Z()
z_obj.freq = freq_arr.copy()
z_obj.z = np.zeros((freq_arr.size, 2, 2), dtype=np.complex)
z_obj.z_err = np.zeros((freq_arr.size, 2, 2), dtype=np.float)
try:
    z_obj.rotation_angle = data_dict["zrot"]
except KeyError:
    z_obj.rotation_angle = np.zeros_like(freq_arr)

z_obj.z[:, 0, 0] = np.array(data_dict["zxxr"]) + np.array(data_dict["zxxi"]) * 1j
z_obj.z[:, 0, 1] = np.array(data_dict["zxyr"]) + np.array(data_dict["zxyi"]) * 1j
z_obj.z[:, 1, 0] = np.array(data_dict["zyxr"]) + np.array(data_dict["zyxi"]) * 1j
z_obj.z[:, 1, 1] = np.array(data_dict["zyyr"]) + np.array(data_dict["zyyi"]) * 1j

z_obj.z_err[:, 0, 0] = np.array(data_dict["zxx.var"])
z_obj.z_err[:, 0, 1] = np.array(data_dict["zxy.var"])
示例#17
0
文件: mt_old.py 项目: zy911k24/mtpy
    def interpolate(self, new_freq_array, interp_type='slinear'):
        """
        Interpolate the impedance tensor onto different frequencies
        
        
        Arguments
        ------------
        
            *new_freq_array* : np.ndarray 
                               a 1-d array of frequencies to interpolate on
                               to.  Must be with in the bounds of the existing
                               frequency range, anything outside and an error
                               will occur.
                               
        Returns
        -----------
        
            *new_z_object* : mtpy.core.z.Z object
                             a new impedance object with the corresponding
                             frequencies and components.
                             
            *new_tipper_object* : mtpy.core.z.Tipper object
                             a new tipper object with the corresponding
                             frequencies and components.
                             
       
        Examples
        ----------
       
        :Interpolate: ::
         
            >>> import mtpy.core.mt as mt
            >>> edi_fn = r"/home/edi_files/mt_01.edi"
            >>> mt_obj = mt.MT(edi_fn)
            >>> # create a new frequency range to interpolate onto
            >>> new_freq = np.logspace(-3, 3, 24)
            >>> new_z_object, new_tipper_obj = mt_obj.interpolate(new_freq)
            >>> mt_obj.write_edi_file(new_fn=r"/home/edi_files/mt_01_interp.edi",
            >>> ...                   new_Z=new_z_object,
            >>> ...                   new_Tipper=new_tipper_object)
            
        """
        # if the interpolation module has not been loaded return
        if interp_import is False:
            print('could not interpolate, need to install scipy')
            return

        #make sure the input is a numpy array
        if type(new_freq_array) != np.ndarray:
            new_freq_array = np.array(new_freq_array)

        # check the bounds of the new frequency array
        if self.Z.freq.min() > new_freq_array.min():
            raise ValueError('New frequency minimum of {0:.5g}'.format(new_freq_array.min())+\
                             ' is smaller than old frequency minimum of {0:.5g}'.format(self.Z.freq.min())+\
                             '.  The new frequency range needs to be within the '+\
                             'bounds of the old one.')
        if self.Z.freq.max() < new_freq_array.max():
            raise ValueError('New frequency maximum of {0:.5g}'.format(new_freq_array.max())+\
                             'is smaller than old frequency maximum of {0:.5g}'.format(self.Z.freq.max())+\
                             '.  The new frequency range needs to be within the '+\
                             'bounds of the old one.')

        # make a new Z object
        new_Z = MTz.Z(z_array=np.zeros((new_freq_array.shape[0], 2, 2),
                                       dtype='complex'),
                      z_err_array=np.zeros((new_freq_array.shape[0], 2, 2)),
                      freq=new_freq_array)

        new_Tipper = MTz.Tipper(tipper_array=np.zeros(
            (new_freq_array.shape[0], 1, 2), dtype='complex'),
                                tipper_err_array=np.zeros(
                                    (new_freq_array.shape[0], 1, 2)),
                                freq=new_freq_array)

        # interpolate the impedance tensor
        for ii in range(2):
            for jj in range(2):
                # need to look out for zeros in the impedance
                # get the indicies of non-zero components
                nz_index = np.nonzero(self.Z.z[:, ii, jj])

                if len(nz_index[0]) == 0:
                    continue
                # get the non-zero components
                z_real = self.Z.z[nz_index, ii, jj].real
                z_imag = self.Z.z[nz_index, ii, jj].imag
                z_err = self.Z.z_err[nz_index, ii, jj]

                # get the frequencies of non-zero components
                f = self.Z.freq[nz_index]

                # get frequencies to interpolate on to, making sure the
                # bounds are with in non-zero components
                new_nz_index = np.where((new_freq_array >= f.min())
                                        & (new_freq_array <= f.max()))
                new_f = new_freq_array[new_nz_index]

                # create a function that does 1d interpolation
                z_func_real = spi.interp1d(f, z_real, kind=interp_type)
                z_func_imag = spi.interp1d(f, z_imag, kind=interp_type)
                z_func_err = spi.interp1d(f, z_err, kind=interp_type)

                # interpolate onto new frequency range
                new_Z.z[new_nz_index, ii,
                        jj] = z_func_real(new_f) + 1j * z_func_imag(new_f)
                new_Z.z_err[new_nz_index, ii, jj] = z_func_err(new_f)

        # if there is not tipper than skip
        if self.Tipper.tipper is None:
            return new_Z, new_Tipper

        # interpolate the Tipper
        for jj in range(2):
            # get indicies of non-zero components
            nz_index = np.nonzero(self.Tipper.tipper[:, 0, jj])

            if len(nz_index[0]) == 0:
                continue

            # get non-zero components
            t_real = self.Tipper.tipper[nz_index, 0, jj].real
            t_imag = self.Tipper.tipper[nz_index, 0, jj].imag
            t_err = self.Tipper.tipper_err[nz_index, 0, jj]

            # get frequencies for non-zero components
            f = self.Tipper.freq[nz_index]

            # create interpolation functions
            t_func_real = spi.interp1d(f, t_real, kind=interp_type)
            t_func_imag = spi.interp1d(f, t_imag, kind=interp_type)
            t_func_err = spi.interp1d(f, t_err, kind=interp_type)

            # get new frequency to interpolate over, making sure bounds are
            # for non-zero components
            new_nz_index = np.where((new_freq_array >= f.min())
                                    & (new_freq_array <= f.max()))
            new_f = new_freq_array[new_nz_index]

            # interpolate onto new frequency range
            new_Tipper.tipper[new_nz_index, 0, jj] = t_func_real(new_f)+\
                                                  1j*t_func_imag(new_f)

            new_Tipper.tipper_err[new_nz_index, 0, jj] = t_func_err(new_f)

        return new_Z, new_Tipper
示例#18
0
    line = line.strip().split()
    if len(line) < 2:
        break
    else:
        mlst.append({})
    for ii, key in enumerate(mkeys):
        if ii == 0:
            mlst[jj][key] = line[ii]
        elif ii == 1:
            nedi = line[1][1:-1]
            nedi = nedi.split(',')
            mlst[jj][key] = [
                os.path.join(edipath, edistem + kk + '.edi') for kk in nedi
            ]
        elif ii == 2:
            mlst[jj][key] = Z.Z(os.path.join(edipath, line[ii] + '.edi'))
        else:
            #            if ii==5:
            #                #conversion of feet to meters
            #                mlst[jj][key]=float(line[ii])
            #            else:
            #               mlst[jj][key]=float(line[ii])
            mlst[jj][key] = float(line[ii])

#==============================================================================
# read in impedance and stack for each station
#==============================================================================
ns = len(mlst)

for ll in range(ns):
    z1 = mlst[ll]['model-sounding'].z.copy()
示例#19
0
    count += len(f_index[0])

    
# now replace
data_arr = data_arr[np.nonzero(data_arr['freq'])]
sort_index = np.argsort(data_arr['freq'])

# check to see if the sorted indexes are descending or ascending,
# make sure that frequency is descending
if data_arr['freq'][0] > data_arr['freq'][1]:
    sort_index = sort_index[::-1]
    
data_arr = data_arr[sort_index]
new_z = z.Z(data_arr['z'],
            data_arr['z_err'],
            data_arr['freq'])

# check for all zeros in tipper, meaning there is only 
# one unique value                    
if np.unique(data_arr['tipper']).size > 1:
    new_t = z.Tipper(data_arr['tipper'], 
                     data_arr['tipper_err'],
                     data_arr['freq'])
                 
else:
    new_t = z.Tipper()
    
mt_obj = mt.MT(edi_01)
mt_obj.Z = new_z
mt_obj.Tipper = new_t      
示例#20
0
def remove_distortion(z_array=None, z_object=None, num_freq=None, g='det'):
    """
    remove distortion from an impedance tensor using the method outlined by 
    Bibby et al., [2005].
    
    Parameters
    -----------
    
        **z_array** : np.ndarray((nf, 2, 2))
                      numpy array of impedance tensor
                      *default* is None
                      
        **z_object** : mtpy.core.z object
                       *default* is None

        **num_freq** : int
                       number of frequecies to look for distortion
                       *default* is None, meaning look over all frequencies

        **g** : [ 'det' | '01' | '10 ]
                type of distortion to look for
                *default* is 'det'

    Returns
    --------

        **distortion** : np.ndarray (2, 2)
                         distortion array

        **new_z_obj** : mtpy.core.z
                        z object with distortion removed and error calculated

    Examples
    -------------

        :Remove Distortion: ::

            >>> import mtpy.analysis.distortion as distortion
            >>> d, new_z = distortion.remove_distortion(z_object=z_obj)                         
    """

    if z_array is not None:
        z_obj = MTz.Z(z_array=z_array)

    elif z_object is not None:
        z_obj = z_object

    zero_idx = np.where(z_obj.z == 0 + 0j)

    # 0. generate a Z object
    # 1. find distortion via function above,
    # 2. remove distortion via method of z object

    dis, dis_err = find_distortion(z_obj, num_freq=num_freq, g=g)

    try:
        # distortion_tensor, zd, zd_err = z_obj.no_distortion(dis, distortion_err_tensor=dis_err)
        distortion_tensor, zd, zd_err = z_obj.remove_distortion(
            dis, distortion_err_tensor=dis_err)

        zd_err = np.nan_to_num(zd_err)
        zd_err[np.where(zd_err == 0.0)] = 1.0
        distortion_z_obj = z_obj
        distortion_z_obj.z = zd
        distortion_z_obj.z[zero_idx] = 0.0 + 0.0j
        distortion_z_obj.z_err = zd_err

        return distortion_tensor, distortion_z_obj

    except MTex.MTpyError_Z:
        print('Could not compute distortion tensor')

        return np.identity(2), z_obj
    line = line.strip().split()
    if len(line) < 2:
        break
    else:
        mlst.append({})
    for ii, key in enumerate(mkeys):
        if ii == 0:
            mlst[jj][key] = line[ii]
        elif ii == 1:
            nedi = line[1][1:-1]
            nedi = nedi.split(",")
            mlst[jj][key] = [
                os.path.join(edipath, edistem + kk + ".edi") for kk in nedi
            ]
        elif ii == 2:
            mlst[jj][key] = Z.Z(os.path.join(edipath, line[ii] + ".edi"))
        else:
            #            if ii==5:
            #                #conversion of feet to meters
            #                mlst[jj][key]=float(line[ii])
            #            else:
            #               mlst[jj][key]=float(line[ii])
            mlst[jj][key] = float(line[ii])

# ==============================================================================
# read in impedance and stack for each station
# ==============================================================================
ns = len(mlst)

for ll in range(ns):
    z1 = mlst[ll]["model-sounding"].z.copy()