Exemple #1
0
def eccentricity(z_array = None, z_object = None, pt_array= None, pt_object = None):


    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array = z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z('Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object = z_object)
    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array= pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT('Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    lo_ecc = []
    lo_eccerr = []

    if not isinstance(pt_obj, MTpt.PhaseTensor):
        raise MTex.MTpyError_PT('Input argument is not an instance of the PhaseTensor class')
   

    for idx_f in range(len(pt_obj.pt)):
        lo_ecc.append( pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f] )

        ecc_err = None
        if (pt_obj._pi1()[1] is not None) and (pt_obj._pi2()[1] is not None):
            ecc_err = np.sqrt( (pt_obj._pi1()[1][idx_f] /pt_obj._pi1()[0][idx_f] )**2 + (pt_obj._pi2()[1][idx_f] /pt_obj._pi2()[0][idx_f])**2)  


        lo_eccerr.append(ecc_err)

    return np.array(lo_ecc), np.array(lo_eccerr) 
Exemple #2
0
def strike_angle(z_array=None,
                 z_object=None,
                 pt_array=None,
                 pt_object=None,
                 beta_threshold=5,
                 eccentricity_threshold=0.1):

    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array=z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z(
                'Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object=z_object)

    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array=pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT(
                'Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    lo_dims = dimensionality(pt_object=pt_obj,
                             beta_threshold=beta_threshold,
                             eccentricity_threshold=eccentricity_threshold)

    lo_strikes = []

    for idx, dim in enumerate(lo_dims):
        if dim == 1:
            lo_strikes.append((np.nan, np.nan))
            continue

        a = pt_obj.alpha[0][idx]
        b = pt_obj.beta[0][idx]

        strike1 = (a - b) % 90
        if 0 < strike1 < 45:
            strike2 = strike1 + 90
        else:
            strike2 = strike1 - 90

        s1 = min(strike1, strike2)
        s2 = max(strike1, strike2)

        lo_strikes.append((s1, s2))

    return np.array(lo_strikes)
Exemple #3
0
 def _read_edi_file(self):
     """
     read in edi file and set attributes accordingly
     
     """
     
     self.edi_object = MTedi.Edi(self.fn, datatype=self._data_type)
     self.lat = self.edi_object.lat
     self.lon = self.edi_object.lon
     self.elev = self.edi_object.elev
     self.Z = self.edi_object.Z
     self.Tipper = self.edi_object.Tipper
     self.station = self.edi_object.station
     
     #--> get utm coordinates from lat and lon        
     self._get_utm()
     
     #--> make sure things are ordered from high frequency to low
     self._check_freq_order()
     
     #--> compute phase tensor
     self.pt = MTpt.PhaseTensor(z_object=self.Z, freq=self.Z.freq)
     
     #--> compute invariants 
     self.zinv = MTinv.Zinvariants(z_object=self.Z)
Exemple #4
0
def dimensionality(z_array=None,
                   z_object=None,
                   pt_array=None,
                   pt_object=None,
                   beta_threshold=5,
                   eccentricity_threshold=0.1):
    """
    beta_threshold: angle in degrees - if beta is smaller than this, it's 2d
    
    eccentricity_threshold: fraction of eccentricity (0: circle - 1: line) -
    if eccentricity (ellipticity) is small than this, it's a 1D geometry.

    """

    lo_dimensionality = []

    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array=z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z(
                'Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object=z_object)
    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array=pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT(
                'Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    #use criteria from Bibby et al. 2005 for determining the dimensionality for each frequency of the pt/z array:
    for idx_f in range(len(pt_obj.pt)):
        #1. determine beta value...
        beta = pt_obj.beta[0][idx_f]
        #compare with threshold for 3D
        if beta > beta_threshold:
            lo_dimensionality.append(3)
        else:
            #2.check for eccentricity:
            ecc = pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f]
            if ecc > eccentricity_threshold:
                lo_dimensionality.append(2)
            else:
                lo_dimensionality.append(1)

    return np.array(lo_dimensionality)
Exemple #5
0
 def _set_Z(self, z_object):
     """
     set z_object
     
     recalculate phase tensor and invariants, which shouldn't change except
     for strike angle
     """
     
     self._Z = z_object
     self._Z._compute_res_phase()
     
     #--> compute phase tensor
     self.pt = MTpt.PhaseTensor(z_object=self._Z, freq=self._Z.freq)
     
     #--> compute invariants 
     self.zinv = MTinv.Zinvariants(z_object=self._Z) 
Exemple #6
0
        #        z1det=.2*period*abs(np.array([np.sqrt(np.linalg.det(zz)) for zz in z1]))**2
        #        z2det=.2*period*abs(np.array([np.sqrt(np.linalg.det(zz)) for zz in z2]))**2
        z1det = np.array([np.sqrt(abs(np.linalg.det(zz))) for zz in z1])
        z2det = np.array([np.sqrt(abs(np.linalg.det(zz))) for zz in z2])

        zdet = (abs(z1det - z2det) / z1det) * 100

        replst.append((abs(z1det - z2det) / z1det) * 100)

        #        dr1,dp1,zd1=implst[0].getResPhaseDet()
        #        dr2,dp2,zd2=implst[1].getResPhaseDet()
        #
        #        preplst.append((abs(dp1[0]-dp2[0])/dp1[0])*100)

        # ---Phase tensor determinant---
        ptdict1 = mtpt.PhaseTensor(z_object=implst[0].Z)
        ptdict2 = mtpt.PhaseTensor(z_object=implst[1].Z)

        ptd1 = np.array([
            np.sqrt(np.linalg.det(pt1)) * (180 / np.pi) for pt1 in ptdict1.pt
        ])
        ptd2 = np.array([
            np.sqrt(np.linalg.det(pt2)) * (180 / np.pi) for pt2 in ptdict2.pt
        ])
        ptlst.append((abs(ptd1 - ptd2) / ptd1) * 100)

        ptdet = (abs(ptd1 - ptd2) / ptd1) * 100

        for freq, zz, pp in zip(1.0 / period, zdet, ptdet):
            lines.append("{0:<12}{1:>12.2f}{2:>12.2f}\n".format(freq, zz, pp))
def generate_ptcrossdata_file(edi_object,
                              n_iterations,
                              sigma_scaling,
                              outdir,
                              outfn=None):

    freqs = edi_object.freq

    station = edi_object.station
    #no spaces in file names:
    if len(station.split()) > 1:
        station = '_'.join(station.split())

    #Define and check validity of output file
    if outfn is None:
        fn = '{0}_PTcrossdata'.format(station)
        outfn = op.join(outdir, fn)

    outfn = op.realpath(outfn)

    try:
        Fout = open(outfn, 'w')
    except:
        print '\n\tERROR - Cannot generate output file!\n'
        raise
    if n_iterations == 0:
        Fout.write('# {0}   {1:+010.6f}   {2:+011.6f}\n'.format(
            station, edi_object.lat, edi_object.lon))
    else:
        Fout.write(
            '# {0}   {1:+010.6f}   {2:+011.6f} \t\t statistical evaluation of {3} realisations\n'
            .format(station, edi_object.lat, edi_object.lon,
                    abs(int(n_iterations))))
    headerstring = '# lat \t\t lon \t\t freq \t\t Pmin  sigma \t Pmax  sigma \t alpha  '\
                    'sigma \t beta  sigma \t ellipticity  \n'
    Fout.write(headerstring)

    if n_iterations == 0:

        pt = MTpt.PhaseTensor(z_object=edi_object.Z, freq=freqs)

        a = pt.alpha
        b = pt.beta

        phimin = pt.phimin[0]
        phiminerr = pt.phimin[1]
        phimax = pt.phimax[0]
        phimaxerr = pt.phimax[1]

        #e = pt.ellipticity
        #e = (pmax-pmin)/(pmax+pmin)

        for i, freq in enumerate(edi_object.freq):
            try:
                e = (phimax[i] - phimin[i]) / (phimax[i] + phimin[i])
                vals = '{10:.4f}\t{11:.4f}\t{0:.4e}\t{1: 3.2f}\t{2:3.2f}\t{3: 3.2f}\t{4:3.2f}\t{5: 3.2f}\t{6:3.2f}'\
                '\t{7: 3.2f}\t{8:3.2f}\t{9:.3f}\n'.format(
                    freq,phimin[i],phiminerr[i],phimax[i], phimaxerr[i],a[0][i]%90,a[1][i]%90,
                    b[0][i],b[1][i],e,edi_object.lat,edi_object.lon)
                Fout.write(vals)
            except:
                raise
                continue

        Fout.close()
        print '\n\t Done - Written data to file: {0}\n'.format(outfn)
        return

    # for all values n_iterations !=0 loop over abs(n_iterations) #
    # loops individual per frequency

    for idx, f in enumerate(freqs):

        z = edi_object.Z.z
        zerr = edi_object.Z.zerr

        lo_pts = []
        lo_ptserr = []

        cur_z = z[idx]
        cur_zerr = zerr[idx]

        #crude check for 'bad' values in zerr:
        for i in np.arange(4):
            a = cur_zerr[i / 2, i % 2]
            val = cur_z[i / 2, i % 2]

            try:
                dummy = float(a)
                if np.isnan(a) or np.isinf(a):
                    raise
            except:
                #correct by nearest neighbour value
                print f, '\ncorrecting error value', a, '...',
                rel_errs = []
                if idx + 1 != len(freqs):
                    next_z = z[idx + 1][i / 2, i % 2]
                    next_zerr = zerr[idx + 1][i / 2, i % 2]
                    rel_err = next_zerr / abs(next_z)
                    rel_errs.append(rel_err)
                if idx != 0:
                    last_z = z[idx - 1][i / 2, i % 2]
                    last_zerr = zerr[idx - 1][i / 2, i % 2]
                    rel_err = last_zerr / abs(last_z)
                    rel_errs.append(rel_err)
                rel_err_final = np.mean(rel_errs)
                err = rel_err_final * abs(val)
                cur_zerr[i / 2, i % 2] = err
                #print err

        #calculate random numbers:
        lo_rands = []
        for k in np.arange(4):
            randnums = sigma_scaling * cur_zerr[k / 2,
                                                k % 2] * np.random.randn(
                                                    2 * abs(int(n_iterations)))
            lo_rands.append(randnums)

        #Loop over |n_iterations| random realisations:

        lo_pmin = []
        lo_pmax = []

        lo_alphas = []
        lo_betas = []
        #lo_ellipticities = []

        #print 'running {0} iterations for {1} Hz'.format(n_iterations,f)
        for run in np.arange(abs(int(n_iterations))):
            tmp_z = np.array(
                [[
                    complex(
                        np.real(cur_z[0, 0]) + lo_rands[0][run],
                        np.imag(cur_z[0, 0]) + lo_rands[0][-run - 1]),
                    complex(
                        np.real(cur_z[0, 1]) + lo_rands[1][run],
                        np.imag(cur_z[0, 1]) + lo_rands[1][-run - 1])
                ],
                 [
                     complex(
                         np.real(cur_z[1, 0]) + lo_rands[2][run],
                         np.imag(cur_z[1, 0]) + lo_rands[2][-run - 1]),
                     complex(
                         np.real(cur_z[1, 1]) + lo_rands[3][run],
                         np.imag(cur_z[1, 1]) + lo_rands[3][-run - 1])
                 ]])
            tmp_pt = MTpt.PhaseTensor(z_array=tmp_z.reshape(1, 2, 2),
                                      freq=f.reshape(1))
            pi1 = tmp_pt._pi1()[0]
            pi2 = tmp_pt._pi2()[0]
            lo_pmin.append(pi2 - pi1)
            lo_pmax.append(pi2 + pi1)

            alpha = tmp_pt.alpha[0][0]
            if alpha < 0 and alpha % 90 < 10:
                lo_alphas.append(alpha % 90 + 90)
            else:
                lo_alphas.append(alpha % 90)

            # if idx%10==0:
            #     print alpha,lo_alphas[-1]

            lo_betas.append(tmp_pt.beta[0][0])
            #in percent:
            #lo_ellipticities.append(100*tmp_pt.ellipticity[0][0])

        lo_alphas = np.array(lo_alphas)
        a = np.median(lo_alphas)
        aerr = np.median(np.abs(lo_alphas - a))
        #aerr = np.std(lo_alphas)
        # if idx%10==0:
        #     print '\t',a,aerr
        #     print

        b = np.mean(lo_betas)
        berr = np.std(lo_betas)

        #ipdb.set_trace()

        #convert to angles:
        phimin = np.mean([np.degrees(np.arctan(i)) for i in lo_pmin])
        phiminerr = np.std([np.degrees(np.arctan(i)) for i in lo_pmin])

        phimax = np.mean([np.degrees(np.arctan(i)) for i in lo_pmax])
        phimaxerr = np.std([np.degrees(np.arctan(i)) for i in lo_pmax])

        #e = np.mean(lo_ellipticities)
        #eerr = np.std(lo_ellipticities)
        e = (phimax - phimin) / (phimax + phimin)

        try:
            vals = '{10:.4f}\t{11:.4f}\t{0:.4e}\t{1: 3.2f}\t{2:3.2f}\t{3: 3.2f}\t{4:3.2f}\t{5: 3.2f}\t{6:3.2f}'\
            '\t{7: 3.2f}\t{8:3.2f}\t{9:.3f}\n'.format(
                f,phimin,phiminerr,phimax, phimaxerr,a,aerr, b,berr,e,edi_object.lat,edi_object.lon)
            Fout.write(vals)
        except:
            raise
            continue

    Fout.close()
    print '\n\t Done - Written data to file: {0}\n'.format(outfn)
    return
Exemple #8
0
    def _compute_residual_pt(self):
        """
        compute residual phase tensor so the result is something useful to 
        plot
        """
        log_path = os.path.dirname(os.path.dirname(self.fn_list1[0]))
        log_fn = os.path.join(log_path, 'Residual_PT.log')
        logfid = file(log_fn, 'w')

        self._get_freq_list()
        freq_dict = dict([(np.round(key, 5), value)
                          for value, key in enumerate(self.freq_list)])

        num_freq = self.freq_list.shape[0]
        num_station = len(self.mt_list1)

        #make a structured array to put stuff into for easier manipulation
        self.rpt_array = np.zeros(num_station,
                                  dtype=[('station', '|S10'),
                                         ('freq', (np.float, num_freq)),
                                         ('lat', np.float), ('lon', np.float),
                                         ('elev', np.float),
                                         ('offset', np.float),
                                         ('phimin', (np.float, num_freq)),
                                         ('phimax', (np.float, num_freq)),
                                         ('skew', (np.float, num_freq)),
                                         ('azimuth', (np.float, num_freq)),
                                         ('geometric_mean', (np.float,
                                                             num_freq))])

        self.residual_pt_list = []
        for mm, mt1 in enumerate(self.mt_list1):
            station_find = False
            fdict1 = dict([(np.round(ff, 5), ii)
                           for ii, ff in enumerate(mt1.freq)])
            for mt2 in self.mt_list2:
                if mt2.station == mt1.station:
                    logfid.write('{0}{1}{0}\n'.format('=' * 30, mt1.station))
                    fdict2 = dict([(np.round(ff, 5), ii)
                                   for ii, ff in enumerate(mt2.freq)])

                    #need to make sure only matched frequencies are compared
                    index_1 = []
                    index_2 = []
                    for key1 in sorted(fdict1.keys()):
                        try:
                            index_2.append(fdict2[key1])
                            index_1.append(fdict1[key1])
                            logfid.write('-' * 20 + '\n')
                            logfid.write('found {0} in both\n'.format(key1))
                            logfid.write('Index 1={0}, Index 2={1}\n'.format(
                                fdict1[key1], fdict2[key1]))
                        except KeyError:
                            'Did not find {0:.4e} Hz in {1}'.format(
                                key1, mt2.fn)

                    #need to sort the index list, otherwise weird things happen
                    index_1.sort()
                    index_2.sort()

                    #create new Z objects that have similar frequencies
                    new_z1 = mtpl.mtz.Z(z_array=mt1.z[index_1],
                                        zerr_array=mt1.z_err[index_1],
                                        freq=mt1.freq[index_1])
                    new_z2 = mtpl.mtz.Z(z_array=mt2.z[index_2],
                                        zerr_array=mt2.z_err[index_2],
                                        freq=mt2.freq[index_2])

                    #make new phase tensor objects
                    pt1 = mtpt.PhaseTensor(z_object=new_z1)
                    pt2 = mtpt.PhaseTensor(z_object=new_z2)

                    #compute residual phase tensor
                    rpt = mtpt.ResidualPhaseTensor(pt1, pt2)
                    rpt.compute_residual_pt(pt1, pt2)

                    #add some attributes to residual phase tensor object
                    rpt.station = mt1.station
                    rpt.lat = mt1.lat
                    rpt.lon = mt1.lon

                    #append to list for manipulating later
                    self.residual_pt_list.append(rpt)

                    #be sure to tell the program you found the station
                    station_find = True

                    #put stuff into an array because we cannot set values of
                    #rpt, need this for filtering.
                    st_1, st_2 = self.station_id
                    self.rpt_array[mm]['station'] = mt1.station[st_1:st_2]
                    self.rpt_array[mm]['lat'] = mt1.lat
                    self.rpt_array[mm]['lon'] = mt1.lon
                    self.rpt_array[mm]['elev'] = mt1.elev
                    self.rpt_array[mm]['freq'][:] = self.freq_list

                    rpt_fdict = dict([(np.round(key, 5), value)
                                      for value, key in enumerate(rpt.freq)])

                    for f_index, freq in enumerate(rpt.freq):
                        aa = freq_dict[np.round(freq, 5)]
                        try:
                            rr = rpt_fdict[np.round(freq, 5)]
                            try:
                                self.rpt_array[mm]['phimin'][aa] = \
                                            rpt.residual_pt.phimin[0][rr]
                                self.rpt_array[mm]['phimax'][aa] = \
                                            rpt.residual_pt.phimax[0][rr]
                                self.rpt_array[mm]['skew'][aa] = \
                                            rpt.residual_pt.beta[0][rr]
                                self.rpt_array[mm]['azimuth'][aa] = \
                                            rpt.residual_pt.azimuth[0][rr]
                                self.rpt_array[mm]['geometric_mean'][aa] = \
                                    np.sqrt(abs(rpt.residual_pt.phimin[0][rr]*
                                                rpt.residual_pt.phimax[0][rr]))
                                logfid.write('Freq={0:.5f} '.format(freq))
                                logfid.write('Freq_list_index={0} '.format(
                                    np.where(self.freq_list == freq)[0][0]))
                                logfid.write('rpt_array_index={0} '.format(aa))
                                logfid.write('rpt_dict={0} '.format(rr))
                                logfid.write('rpt.freq_index={0} '.format(
                                    np.where(rpt.freq == freq)[0][0]))
                                logfid.write('Phi_max={0:2f} '.format(
                                    rpt.residual_pt.phimax[0][rr]))
                                logfid.write('Phi_min={0:2f} '.format(
                                    rpt.residual_pt.phimin[0][rr]))
                                logfid.write('Skew={0:2f} '.format(
                                    rpt.residual_pt.beta[0][rr]))
                                logfid.write('Azimuth={0:2f}\n'.format(
                                    rpt.residual_pt.azimuth[0][rr]))

                            except IndexError:
                                print '-' * 50
                                print mt1.station
                                print 'freq_index for 1:  {0}'.format(f_index)
                                print 'freq looking for:  {0}'.format(freq)
                                print 'index in big    :  {0}'.format(aa)
                                print 'index in 1      :  {0} '.format(rr)
                                print 'len_1 = {0}, len_2 = {1}'.format(
                                    len(mt2.freq), len(mt1.freq))
                                print 'len rpt_freq = {0}'.format(len(
                                    rpt.freq))
                        except KeyError:
                            print 'Station {0} does not have {1:.5f}Hz'.format(
                                mt1.station, freq)

                    break
                else:
                    pass
            if station_find == False:
                print 'Did not find {0} from list 1 in list 2'.format(
                    mt1.station)

        # from the data get the relative offsets and sort the data by them
        self._get_offsets()

        logfid.close()
        #write Marina's format
        rp_lines_base = []
        rp_lines_base.append(
            ''.join(['{0:^12}'.format(hh) for hh in header_line] + ['\n']))
        rp_lines_inj = []
        rp_lines_inj.append(
            ''.join(['{0:^12}'.format(hh) for hh in header_line] + ['\n']))

        pt_lines_base = []
        pt_lines_base.append(
            ''.join(['{0:^12}'.format(hh) for hh in header_line_pt] + ['\n']))
        pt_lines_inj = []
        pt_lines_inj.append(
            ''.join(['{0:^12}'.format(hh) for hh in header_line_pt] + ['\n']))

        pt_base = mtpt.PhaseTensor(z_object=edi_base.Z)
        pt_inj = mtpt.PhaseTensor(z_object=edi_inj.Z)

        for ii, freq in enumerate(edi_base.Z.freq):
            rp_lines_base.append(''.join([
                '{0:>12}'.format(nn) for nn in [
                    '{0:+.4e}'.format(mm) for mm in [
                        1. / freq, edi_base.Z.resistivity[ii, 0, 1], edi_base.
                        Z.resistivity_err[ii, 0,
                                          1], edi_base.Z.resistivity[ii, 1, 0],
                        edi_base.Z.resistivity_err[ii, 1, 0], edi_base.Z.phase[
                            ii, 0, 1], edi_base.Z.phase_err[ii, 0, 1], edi_base
                        .Z.phase[ii, 1, 0], edi_base.Z.phase_err[ii, 1, 0]
                    ]
                ]
            ] + ['\n']))
Exemple #10
0
    def create_measurement_csv(self,
                               dest_dir,
                               period_list=None,
                               interpolate=True):
        """
        create csv file from the data of EDI files: IMPEDANCE, APPARENT RESISTIVITIES AND PHASES
        see also utils/shapefiles_creator.py

        :param dest_dir: output directory
        :param period_list: list of periods; default=None, in which data for all available
                            frequencies are output
        :param interpolate: Boolean to indicate whether to interpolate data onto given period_list

        :return: csvfname
        """
        if dest_dir is None:
            dest_dir = self.outdir
        else:
            self._logger.info("result will be in the dir %s", dest_dir)
            if not os.path.exists(dest_dir):
                os.mkdir(dest_dir)

        # summary csv file
        csv_basename = "edi_measurement"
        csvfname = os.path.join(dest_dir, "%s.csv" % csv_basename)

        pt_dict = {}

        csv_header = [
            'FREQ', 'STATION', 'LAT', 'LON', 'ZXXre', 'ZXXim', 'ZXYre',
            'ZXYim', 'ZYXre', 'ZYXim', 'ZYYre', 'ZYYim', 'TXre', 'TXim',
            'TYre', 'TYim', 'RHOxx', 'RHOxy', 'RHOyx', 'RHOyy', 'PHSxx',
            'PHSxy', 'PHSyx', 'PHSyy'
        ]

        freq_list = None
        if (period_list is None):
            freq_list = self.all_frequencies
        else:
            freq_list = 1. / np.array(period_list)
        # end if

        with open(csvfname, "wb") as csvf:
            writer = csv.writer(csvf)
            writer.writerow(csv_header)

        for freq in freq_list:
            mtlist = []
            for mt_obj in self.mt_obj_list:
                f_index_list = None
                pt = None
                ti = None
                zobj = None
                if (interpolate):
                    f_index_list = [0]

                    newZ = None
                    newTipper = None
                    newZ, newTipper = mt_obj.interpolate([freq],
                                                         bounds_error=False)

                    pt = MTpt.PhaseTensor(z_object=newZ)
                    ti = newTipper
                    zobj = newZ
                else:
                    freq_max = freq * (1 + self.ptol)
                    freq_min = freq * (1 - self.ptol)
                    f_index_list = np.where((mt_obj.Z.freq < freq_max)
                                            & (mt_obj.Z.freq > freq_min))

                    pt = mt_obj.pt
                    ti = mt_obj.Tipper
                    zobj = mt_obj.Z
                # end if

                if len(f_index_list) > 1:
                    self._logger.warn("more than one freq found %s",
                                      f_index_list)

                if len(f_index_list) >= 1:
                    p_index = f_index_list[0]

                    self._logger.debug("The freqs index %s", f_index_list)
                    # geographic coord lat long and elevation
                    # long, lat, elev = (mt_obj.lon, mt_obj.lat, 0)
                    station, lat, lon = (mt_obj.station, mt_obj.lat,
                                         mt_obj.lon)

                    resist_phase = mtplottools.ResPhase(z_object=zobj)
                    # resist_phase.compute_res_phase()

                    mt_stat = [
                        freq, station, lat, lon, zobj.z[p_index, 0, 0].real,
                        zobj.z[p_index, 0, 0].imag, zobj.z[p_index, 0, 1].real,
                        zobj.z[p_index, 0, 1].imag, zobj.z[p_index, 1, 0].real,
                        zobj.z[p_index, 1, 0].imag, zobj.z[p_index, 1, 1].real,
                        zobj.z[p_index, 1, 1].imag, ti.tipper[p_index, 0,
                                                              0].real,
                        ti.tipper[p_index, 0, 0].imag, ti.tipper[p_index, 0,
                                                                 1].real,
                        ti.tipper[p_index, 0,
                                  1].imag, resist_phase.resxx[p_index],
                        resist_phase.resxy[p_index],
                        resist_phase.resyx[p_index],
                        resist_phase.resyy[p_index],
                        resist_phase.phasexx[p_index],
                        resist_phase.phasexy[p_index],
                        resist_phase.phaseyx[p_index],
                        resist_phase.phaseyy[p_index]
                    ]
                    mtlist.append(mt_stat)

                else:
                    self._logger.warn('Freq %s NOT found for this station %s',
                                      freq, mt_obj.station)

            with open(csvfname, "ab") as csvf:  # summary csv for all freqs
                writer = csv.writer(csvf)
                writer.writerows(mtlist)

            csv_basename2 = "%s_%sHz.csv" % (csv_basename, str(freq))
            csvfile2 = os.path.join(dest_dir, csv_basename2)

            with open(csvfile2,
                      "wb") as csvf:  # individual csvfile for each freq
                writer = csv.writer(csvf)

                writer.writerow(csv_header)
                writer.writerows(mtlist)

            pt_dict[freq] = mtlist

        return csvfname
Exemple #11
0
    def create_phase_tensor_csv(self,
                                dest_dir,
                                period_list=None,
                                interpolate=True,
                                file_name="phase_tensor.csv"):
        """
        create phase tensor ellipse and tipper properties.
        Implementation based on mtpy.utils.shapefiles_creator.ShapeFilesCreator.create_csv_files

        :param dest_dir: output directory
        :param period_list: list of periods; default=None, in which data for all available
                            frequencies are output
        :param interpolate: Boolean to indicate whether to interpolate data onto given period_list
        :param file_name: output file name

        :return: pt_dict
        """
        csvfname = os.path.join(dest_dir, file_name)

        pt_dict = {}

        csv_header = [
            'station', 'freq', 'lon', 'lat', 'phi_min', 'phi_max', 'azimuth',
            'skew', 'n_skew', 'elliptic', 'tip_mag_re', 'tip_mag_im',
            'tip_ang_re', 'tip_ang_im'
        ]

        freq_list = None
        if (period_list is None):
            freq_list = self.all_frequencies
        else:
            freq_list = 1. / np.array(period_list)
        # end if

        with open(csvfname, "wb") as csvf:
            writer = csv.writer(csvf)
            writer.writerow(csv_header)

            for freq in freq_list:
                ptlist = []
                for mt_obj in self.mt_obj_list:
                    f_index_list = None
                    pt = None
                    ti = None

                    if (interpolate):
                        f_index_list = [0]

                        newZ = None
                        newTipper = None
                        newZ, newTipper = mt_obj.interpolate(
                            [freq], bounds_error=False)

                        pt = MTpt.PhaseTensor(z_object=newZ)
                        ti = newTipper
                    else:
                        freq_min = freq * (1 - self.ptol)
                        freq_max = freq * (1 + self.ptol)

                        f_index_list = [
                            ff for ff, f2 in enumerate(mt_obj.Z.freq)
                            if (f2 > freq_min) and (f2 < freq_max)
                        ]
                        pt = mt_obj.pt
                        ti = mt_obj.Tipper
                    #end if

                    if len(f_index_list) > 1:
                        self._logger.warn("more than one freq found %s",
                                          f_index_list)
                    if len(f_index_list) >= 1:
                        p_index = f_index_list[0]
                        # geographic coord lat long and elevation
                        # long, lat, elev = (mt_obj.lon, mt_obj.lat, 0)
                        station, lon, lat = (mt_obj.station, mt_obj.lon,
                                             mt_obj.lat)

                        pt_stat = [
                            station,
                            freq,
                            lon,
                            lat,
                            pt.phimin[p_index],
                            pt.phimax[p_index],
                            pt.azimuth[p_index],
                            pt.beta[p_index],
                            2 * pt.beta[p_index],
                            pt.ellipticity[
                                p_index],  # FZ: get ellipticity begin here
                            ti.mag_real[p_index],
                            ti.mag_imag[p_index],
                            ti.angle_real[p_index],
                            ti.angle_imag[p_index]
                        ]

                        ptlist.append(pt_stat)
                    else:
                        self._logger.warn(
                            "Freq %s NOT found for this station %s", freq,
                            mt_obj.station)

                csv_freq_file = os.path.join(
                    dest_dir, '{name[0]}_{freq}Hz{name[1]}'.format(
                        freq=str(freq), name=os.path.splitext(file_name)))
                with open(csv_freq_file, "wb") as freq_csvf:
                    writer_freq = csv.writer(freq_csvf)
                    writer_freq.writerow(csv_header)
                    writer_freq.writerows(ptlist)

                writer.writerows(ptlist)

                pt_dict[freq] = ptlist

        return pt_dict
Exemple #12
0
    def get_phase_tensor_tippers(self, period, interpolate=True):
        """
        For a given MT period (s) value, compute the phase tensor and tippers etc.

        :param period: MT_period (s)
        :param interpolate: Boolean to indicate whether to interpolate on to the given period
        :return: dictionary pt_dict_list

        pt_dict keys ['station', 'freq', 'lon', 'lat', 'phi_min', 'phi_max', 'azimuth', 'skew', 'n_skew', 'elliptic',
                      'tip_mag_re', 'tip_mag_im', 'tip_ang_re', 'tip_ang_im']
        """

        pt_dict_list = []
        plot_per = period
        #plot_per = self.all_unique_periods[1]  # test first

        print("The plot period is ", plot_per)

        for mt_obj in self.mt_obj_list:
            pt_dict = {}
            pt = None
            ti = None

            if (interpolate == False):
                p_index = [
                    ff for ff, f2 in enumerate(1.0 / mt_obj.Z.freq)
                    if (f2 > plot_per * (1 - self.ptol)) and (f2 < plot_per *
                                                              (1 + self.ptol))
                ]

                pt = mt_obj.pt
                ti = mt_obj.Tipper
            else:
                p_index = [0]
                newZ, newTipper = mt_obj.interpolate([1. / plot_per],
                                                     bounds_error=False)

                pt = MTpt.PhaseTensor(z_object=newZ)
                ti = newTipper
            # end if

            if len(p_index) >= 1:
                p_index = p_index[0]
                pt_dict['station'] = mt_obj.station
                pt_dict['period'] = plot_per
                pt_dict['lon'] = mt_obj.lon
                pt_dict['lat'] = mt_obj.lat

                pt_dict['phi_min'] = pt.phimin[p_index]
                pt_dict['phi_max'] = pt.phimax[p_index]
                pt_dict['azimuth'] = pt.azimuth[p_index]
                pt_dict['skew'] = pt.beta[p_index]
                pt_dict['n_skew'] = 2 * pt.beta[p_index]
                pt_dict['elliptic'] = pt.ellipticity[p_index]

                pt_dict['tip_mag_re'] = ti.mag_real[p_index]
                pt_dict['tip_mag_im'] = ti.mag_imag[p_index]
                pt_dict['tip_ang_re'] = ti.angle_real[p_index]
                pt_dict['tip_ang_im'] = ti.angle_imag[p_index]

                pt_dict_list.append(pt_dict)
            else:
                self._logger.warn(
                    " the period %s is NOT found for this station %s. Skipping!!!"
                    % (plot_per, mt_obj.station))

        return pt_dict_list
    phimaxarr = np.zeros((nf, ns))
    phiminarr = np.zeros((nf, ns))
    betaarr = np.zeros((nf, ns))
    colorarr = np.zeros((nf, ns))

    latlst = np.zeros(ns)
    lonlst = np.zeros(ns)

    stationlst = []

    for ss, station in enumerate(edilst):
        #make a data type Z
        edi1 = mtedi.Edi(station[0])
        edi2 = mtedi.Edi(station[1])

        pt1 = mtpt.PhaseTensor(z_object=edi1.Z)
        pt2 = mtpt.PhaseTensor(z_object=edi2.Z)

        stationlst.append(edi1.station)

        sz, se, sn = utm2ll.LLtoUTM(refe, edi1.lat, edi1.lon)
        latlst[ss] = (sn - bhn) / 1000.
        lonlst[ss] = (se - bhe) / 1000.

        #calculate the difference between the two phase tensor ellipses
        for ii in range(nf):
            phi = np.eye(2) - (np.dot(np.linalg.inv(pt1.pt[ii]), pt2.pt[ii]))

            #compute the trace
            tr = phi[0, 0] + phi[1, 1]
            #Calculate skew of phi and the cooresponding error
Exemple #14
0
def dimensionality(z_array=None,
                   z_object=None,
                   pt_array=None,
                   pt_object=None,
                   skew_threshold=5,
                   eccentricity_threshold=0.1):
    """
    Esitmate dimensionality of an impedance tensor, frequency by frequency.

    Dimensionality is estimated from the phase tensor given the threshold
    criteria on the skew angle and eccentricity following Bibby et al., 2005
    and Booker, 2014.

    Arguments
    ------------

        **z_array** : np.ndarray(nf, 2, 2)
                      numpy array of impedance elements
                      *default* is None

        **z_object** : mtpy.core.z.Z
                       z_object
                       *default* is None

        **pt_array** : np.ndarray(nf, 2, 2)
                       numpy array of phase tensor elements
                       *default* is None

        **pt_object** : mtpy.analysis.pt.PT
                        phase tensor object
                        *default* is None

        **skew_threshold** : float
                             threshold on the skew angle in degrees, anything
                             above this value is 3-D or azimuthally anisotropic
                             *default* is 5 degrees

        **eccentricity_threshold** : float
                                     threshold on eccentricty in dimensionaless
                                     units, anything below this value is 1-D
                                     *default* is 0.1

    Returns
    ----------

        **dimensions** : np.ndarray(nf, dtype=int)
                         an array of dimesions for each frequency
                         the values are [ 1 | 2 | 3 ]


    Examples
    ----------
        :Estimate Dimesions: ::

            >>> import mtpy.analysis.geometry as geometry
            >>> dim = geometry.dimensionality(z_object=z_obj,
            >>>                               skew_threshold=3)


    """

    lo_dimensionality = []

    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array=z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z(
                'Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object=z_object)
    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array=pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT(
                'Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    # use criteria from Bibby et al. 2005 for determining the dimensionality
    # for each frequency of the pt/z array:
    for idx_f in range(len(pt_obj.pt)):
        #1. determine skew value...
        skew = pt_obj.beta[idx_f]
        #compare with threshold for 3D
        if np.abs(skew) > skew_threshold:
            lo_dimensionality.append(3)
        else:
            # 2.check for eccentricity:
            ecc = pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f]
            if ecc > eccentricity_threshold:
                lo_dimensionality.append(2)
            else:
                lo_dimensionality.append(1)

    return np.array(lo_dimensionality)
Exemple #15
0
def eccentricity(z_array=None, z_object=None, pt_array=None, pt_object=None):
    """
    Estimate eccentricy of a given impedance or phase tensor object


    Arguments
    ------------

        **z_array** : np.ndarray(nf, 2, 2)
                      numpy array of impedance elements
                      *default* is None

        **z_object** : mtpy.core.z.Z
                       z_object
                       *default* is None

        **pt_array** : np.ndarray(nf, 2, 2)
                       numpy array of phase tensor elements
                       *default* is None

        **pt_object** : mtpy.analysis.pt.PT
                        phase tensor object
                        *default* is None


    Returns
    ----------

        **eccentricity** : np.ndarray(nf)


        **eccentricity_err** : np.ndarray(nf)



    Examples
    ----------
        :Estimate Dimesions: ::

            >>> import mtpy.analysis.geometry as geometry
            >>> ec, ec_err= geometry.eccentricity(z_object=z_obj)
    """

    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array=z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z(
                'Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object=z_object)
    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array=pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT(
                'Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    lo_ecc = []
    lo_eccerr = []

    if not isinstance(pt_obj, MTpt.PhaseTensor):
        raise MTex.MTpyError_PT(
            'Input argument is not an instance of the PhaseTensor class')

    for idx_f in range(len(pt_obj.pt)):
        lo_ecc.append(pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f])

        ecc_err = None
        if (pt_obj._pi1()[1] is not None) and (pt_obj._pi2()[1] is not None):
            ecc_err = np.sqrt((pt_obj._pi1()[1][idx_f] / pt_obj._pi1()[0][idx_f]) ** 2 +\
                              (pt_obj._pi2()[1][idx_f] / pt_obj._pi2()[0][idx_f]) ** 2)

        lo_eccerr.append(ecc_err)

    return np.array(lo_ecc), np.array(lo_eccerr) * np.array(lo_ecc)
Exemple #16
0
def strike_angle(z_array=None,
                 z_object=None,
                 pt_array=None,
                 pt_object=None,
                 skew_threshold=5,
                 eccentricity_threshold=0.1):
    """
    Estimate strike angle from 2D parts of the phase tensor given the
    skew and eccentricity thresholds

        Arguments
    ------------

        **z_array** : np.ndarray(nf, 2, 2)
                      numpy array of impedance elements
                      *default* is None

        **z_object** : mtpy.core.z.Z
                       z_object
                       *default* is None

        **pt_array** : np.ndarray(nf, 2, 2)
                       numpy array of phase tensor elements
                       *default* is None

        **pt_object** : mtpy.analysis.pt.PT
                        phase tensor object
                        *default* is None

        **skew_threshold** : float
                             threshold on the skew angle in degrees, anything
                             above this value is 3-D or azimuthally anisotropic
                             *default* is 5 degrees

        **eccentricity_threshold** : float
                                     threshold on eccentricty in dimensionaless
                                     units, anything below this value is 1-D
                                     *default* is 0.1

    Returns
    ----------

        **strike** : np.ndarray(nf)
                         an array of strike angles in degrees for each frequency
                         assuming 0 is north, and e is 90.  There is a 90
                         degree ambiguity in the angle.


    Examples
    ----------
        :Estimate Dimesions: ::

            >>> import mtpy.analysis.geometry as geometry
            >>> strike = geometry.strike_angle(z_object=z_obj,
            >>>                                skew_threshold=3)

    """

    if z_array is not None:
        pt_obj = MTpt.PhaseTensor(z_array=z_array)
    elif z_object is not None:
        if not isinstance(z_object, MTz.Z):
            raise MTex.MTpyError_Z(
                'Input argument is not an instance of the Z class')
        pt_obj = MTpt.PhaseTensor(z_object=z_object)

    elif pt_array is not None:
        pt_obj = MTpt.PhaseTensor(pt_array=pt_array)
    elif pt_object is not None:
        if not isinstance(pt_object, MTpt.PhaseTensor):
            raise MTex.MTpyError_PT(
                'Input argument is not an instance of the PhaseTensor class')
        pt_obj = pt_object

    lo_dims = dimensionality(pt_object=pt_obj,
                             skew_threshold=skew_threshold,
                             eccentricity_threshold=eccentricity_threshold)

    lo_strikes = []

    for idx, dim in enumerate(lo_dims):
        if dim == 1:
            lo_strikes.append((np.nan, np.nan))


#            continue

        elif dim == 3:
            lo_strikes.append((np.nan, np.nan))

        else:
            a = pt_obj.alpha[idx]
            b = pt_obj.beta[idx]

            strike1 = (a - b) % 180

            # change so that values range from -90 to +90
            # add alternative strikes to account for ambiguity
            if strike1 > 90:
                strike1 -= 180
                strike2 = strike1 + 90
            else:
                strike2 = strike1 - 90

            lo_strikes.append((strike1, strike2))

    return np.array(lo_strikes)