seismo_logs — EQcorrscan 0.1.0 documentation

# Source code for seismo_logs

    """
    Functions to read log-files for seismic data to determine whether there are \
    timing issues present.  Designed to be used with the EQcorrscan package and \
    to flag data that has more than a threshold timing issue.

    Currently only written to read RefTek rt130 log-files.

    Written by Calum Chamberlain, VUW 2015

    Copyright 2015 Calum Chamberlain

    This file is part of EQcorrscan.

        EQcorrscan is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

        EQcorrscan is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with EQcorrscan.  If not, see <http://www.gnu.org/licenses/>.

    """
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    from __future__ import unicode_literals

    def Read_RT_log(logfile, startdate):
        """
        Function to open and read a log-file as written by a RefTek RT130 \
        datalogger. The information within is then scanned for timing errors \
        above the threshold.

        :type logfile: String
        :param logfile: The logfile to look in
        :type startdate: :class: datetime.date
        :param startdate: The start of the file as a date - files contain timing \
            and the julian day, but not the year.
        :type time_thresh: float
        :param time_thresh: Threshold to raise a flag for the data in seconds

        :returns: List of tuple of :class: datetime.datetime, float as time \
            stamps and phase error.
        """
        import datetime as dt
        f = open(logfile, 'r')
        phase_err = []
        lock = []
        # Extract all the phase errors
        for line in f:
            if line[13:39] == "INTERNAL CLOCK PHASE ERROR":
                phase_err.append((dt.datetime.strptime(str(startdate.year) +
                                                       ':'+line[0:12],
                                                       '%Y:%j:%H:%M:%S'),
                                 float(line.split(' ')[-2]) *
                                 0.000001))
            elif line[13:-1].strip() == "EXTERNAL CLOCK POWER IS TURNED OFF":
                lock.append((dt.datetime.strptime(str(startdate.year) +
                                                  ':'+line[0:12],
                                                  '%Y:%j:%H:%M:%S'),
                            999))
        if len(phase_err) == 0 and len(lock) > 0:
            phase_err = lock
        return phase_err

    def Flag_time_err(phase_err, time_thresh=0.02):
        """
        Fucntion to scan through a list of tuples of time stamps and phase errors \
        and return a list of time stamps with timing errors above a threshold.

        :type phase_err: List of Tuple of float, datetime.datetime
        :type time_thresh: float
        :param time_thresh: Threshold to declare a timing error for

        :returns: List of datetime.datetime
        """
        time_err = []
        for stamp in phase_err:
            if abs(stamp[1]) > time_thresh:
                time_err.append(stamp[0])
        return time_err

    def check_all_logs(directory, time_thresh):
        """
        Function to check all the log-files in a directory tree for timing errors.

        :type directory: String
        :param directory: Directory to search within
        :type time_thresh: float
        :param time_thresh: Time threshold in seconds

        :returns: List of :class: datetime.datetime for which timing is above \
            threshold
        """
        import glob
        import sys
        import datetime as dt
        log_files = glob.glob(directory+'/*/0/000000000_00000000')
        print('I have '+str(len(log_files))+' log files to scan')
        total_phase_errs = []
        for i, log_file in enumerate(log_files):
            startdate = dt.datetime.strptime(log_file.split('/')[-4][0:7],
                                             '%Y%j').date()
            total_phase_errs += Read_RT_log(log_file, startdate)
            sys.stdout.write("\r"+str(float(i) / len(log_files) * 100)+"% \r")
            sys.stdout.flush()
        time_errs = Flag_time_err(total_phase_errs, time_thresh)
        time_errs.sort()
        return time_errs, total_phase_errs

    if __name__ == "__main__":
        import doctest
        doctest.testmod()