From 50842b069f36608d57d276c6aa4f2ae6484b4dc4 Mon Sep 17 00:00:00 2001 From: Riley Date: Thu, 12 Oct 2023 13:15:28 -0500 Subject: [PATCH] minor cli updates and vernum --- conda/meta.yaml | 4 +- docs/generate_docs.py | 2 +- docs/main.html | 4817 ------------------- docs/sprit_cli.html | 12 +- docs/sprit_hvsr.html | 2 +- pyproject.toml | 2 +- setup.py | 2 +- sprit/__pycache__/sprit_cli.cpython-311.pyc | Bin 6174 -> 6263 bytes sprit/sprit_cli.py | 6 +- 9 files changed, 18 insertions(+), 4829 deletions(-) delete mode 100644 docs/main.html diff --git a/conda/meta.yaml b/conda/meta.yaml index 3228cc7..19d0b11 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -1,10 +1,10 @@ package: name: sprit - version: 0.1.44 + version: 0.1.45 source: git_url: https://github.com/RJbalikian/SPRIT-HVSR - git_tag: v0.1.44 + git_tag: v0.1.45 build: number: 0 diff --git a/docs/generate_docs.py b/docs/generate_docs.py index da05c74..9be743e 100644 --- a/docs/generate_docs.py +++ b/docs/generate_docs.py @@ -8,7 +8,7 @@ #Whether to convert_md using markdown library (True), or let github do it (False) convert_md=True rtd_theme=False #Not currently working -release_version= '0.1.44' +release_version= '0.1.45' currentDir = pathlib.Path((__file__)).parent docsDir = currentDir diff --git a/docs/main.html b/docs/main.html deleted file mode 100644 index 0c01a43..0000000 --- a/docs/main.html +++ /dev/null @@ -1,4817 +0,0 @@ - - - - - - -sprit API documentation - - - - - - - - - - - -
-
-
-

Package sprit

-
-
-

This module analysis ambient seismic data using the Horizontal to Vertical Spectral Ratio (HVSR) technique

-
- -Expand source code - -
#__init__.py
-"""
-This module analysis ambient seismic data using the Horizontal to Vertical Spectral Ratio (HVSR) technique
-"""
-
-import sprit.sprit_utils as sprit_utils
-import sprit.sprit_gui as sprit_gui
-import sprit.sprit_hvsr as sprit_hvsr
-
-from sprit.sprit_hvsr import(
-    run,
-    export_data,
-    import_data,
-    input_params,
-    gui,
-    get_metadata,
-    fetch_data,
-    batch_data_read,
-    generate_ppsds,
-    process_hvsr,
-    plot_hvsr,
-    remove_noise,
-    check_peaks,
-    get_report,
-    HVSRData,
-    HVSRBatch,
-)
-
-from sprit.sprit_utils import(
-    check_gui_requirements,
-    checkifpath,
-    check_mark,
-    check_tsteps,
-    check_xvalues,
-    format_time,
-    get_char,
-    has_required_channels,
-    make_it_classy,
-    read_from_RS,
-    time_it
-)
-
-from sprit.sprit_gui import(
-    catch_errors
-)
-
-
-__all__ =('sprit_hvsr',
-            'run',
-            'check_mark',
-            'get_char',
-            'time_it',
-            'checkifpath',
-            'export_data', 
-            'import_data',
-            'input_params',
-            'gui',
-            'get_metadata',
-            'has_required_channels',
-            'fetch_data',
-            'batch_data_read',
-            'generate_ppsds',
-            'process_hvsr',
-            'plot_hvsr',
-            'remove_noise',
-            'check_peaks',
-            'get_report',
-            'HVSRData',
-            'HVSRBatch',
-        'sprit_utils',
-            'check_gui_requirements',
-            'checkifpath',
-            'check_mark',
-            'check_tsteps',
-            'check_xvalues',
-            'format_time',
-            'get_char',
-            'has_required_channels',
-            'make_it_classy',
-            'read_from_RS',
-            'time_it',
-        'sprit_gui',
-            'catch_errors'
-            )
-
-__author__ = 'Riley Balikian'
-
-
-
-

Sub-modules

-
-
sprit.sprit_cli
-
-

This module/script is used to run sprit from the command line …

-
-
sprit.sprit_gui
-
-

This script contains all the functions, classes, etc. to create a tkinter app for graphical user interface.

-
-
sprit.sprit_hvsr
-
-

This module is the main SpRIT module that contains all the functions needed to run HVSR analysis …

-
-
sprit.sprit_utils
-
-
-
-
-
-
-
-
-

Functions

-
-
-def batch_data_read(input_data, batch_type='table', param_col=None, batch_params=None, verbose=False, **readcsv_getMeta_fetch_kwargs) -
-
-

Function to read data in data as a batch of multiple data files. This is best used through sprit.fetch_data(args, source='batch', *other_kwargs).

-

Parameters

-
-
input_data : filepath or list
-
Input data information for how to read in data as batch
-
batch_type : str, optional
-
Type of batch read, only 'table' and 'filelist' accepted. If 'table', will read data from a file read in using pandas.read_csv(), by default 'table'
-
param_col : None or str, optional
-
Name of parameter column from batch information file. Only used if a batch_type='table' and single parameter column is used, rather than one column per parameter (for single parameter column, parameters are formatted with = between keys/values and , between item pairs), by default None
-
batch_params : list, dict, or None, default = None
-
Parameters to be used if batch_type='filelist'. If it is a list, needs to be the same length as input_data. If it is a dict, will be applied to all files in input_data and will combined with extra keyword arguments caught by **readcsv_getMeta_fetch_kwargs.
-
verbose : bool, optional
-
Whether to print information to terminal during batch read, by default False
-
**readcsv_getMeta_fetch_kwargs
-
Keyword arguments that will be read into pandas.read_csv(), sprit.input_params, sprit.get_metadata(), and/or sprit.fetch_data()
-
-

Returns

-
-
dict
-
Dictionary with each item representing a different file read in, and which consists of its own parameter dictionary to be used by the rest of the processing steps
-
-

Raises

-
-
IndexError
-
description
-
-
- -Expand source code - -
def batch_data_read(input_data, batch_type='table', param_col=None, batch_params=None, verbose=False, **readcsv_getMeta_fetch_kwargs):
-    """Function to read data in data as a batch of multiple data files. This is best used through sprit.fetch_data(*args, source='batch', **other_kwargs).
-
-    Parameters
-    ----------
-    input_data : filepath or list
-        Input data information for how to read in data as batch
-    batch_type : str, optional
-        Type of batch read, only 'table' and 'filelist' accepted. If 'table', will read data from a file read in using pandas.read_csv(), by default 'table'
-    param_col : None or str, optional
-        Name of parameter column from batch information file. Only used if a batch_type='table' and single parameter column is used, rather than one column per parameter (for single parameter column, parameters are formatted with = between keys/values and , between item pairs), by default None
-    batch_params : list, dict, or None, default = None
-        Parameters to be used if batch_type='filelist'. If it is a list, needs to be the same length as input_data. If it is a dict, will be applied to all files in input_data and will combined with extra keyword arguments caught by **readcsv_getMeta_fetch_kwargs.
-    verbose : bool, optional
-        Whether to print information to terminal during batch read, by default False
-    **readcsv_getMeta_fetch_kwargs
-        Keyword arguments that will be read into pandas.read_csv(), sprit.input_params, sprit.get_metadata(), and/or sprit.fetch_data()
-
-    Returns
-    -------
-    dict
-        Dictionary with each item representing a different file read in, and which consists of its own parameter dictionary to be used by the rest of the processing steps
-
-    Raises
-    ------
-    IndexError
-        _description_
-    """
-    #First figure out columns
-    input_params_params = input_params.__code__.co_varnames
-    get_metadata_params = get_metadata.__code__.co_varnames
-    fetch_data_params = fetch_data.__code__.co_varnames
-
-    if batch_type=='sample':
-        sample_data=True
-        batch_type='table'
-    else:
-        sample_data = False
-    # Dictionary to store the stream objects
-    stream_dict = {}
-    data_dict = {}
-    if batch_type == 'table':
-        if isinstance(input_data, pd.DataFrame):
-            dataReadInfoDF = input_data
-        elif isinstance(input_data, dict):
-            #For params input
-            pass
-        else:#Read csv
-            read_csv_kwargs = {k: v for k, v in locals()['readcsv_getMeta_fetch_kwargs'].items() if k in pd.read_csv.__code__.co_varnames}
-            dataReadInfoDF = pd.read_csv(input_data, **read_csv_kwargs)
-            if 'datapath' in dataReadInfoDF.columns:
-                filelist = list(dataReadInfoDF['datapath'])
-            #dataReadInfoDF = dataReadInfoDF.replace(np.nan, None)
-
-        #If this is sample data, we need to create absolute paths to the filepaths
-        if sample_data:
-            sample_data_dir = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/sample_data/'))
-            for index, row in dataReadInfoDF.iterrows():
-                dataReadInfoDF.loc[index, 'datapath'] = sample_data_dir.joinpath(row.loc['datapath'])
-
-        default_dict = {'site':'HVSR Site',
-                    'network':'AM', 
-                    'station':'RAC84', 
-                    'loc':'00', 
-                    'channels':['EHZ', 'EHN', 'EHE'],
-                    'acq_date':str(datetime.datetime.now().date()),
-                    'starttime' : '00:00:00.00',
-                    'endtime' : '23:59:59.999',
-                    'tzone' : 'UTC',
-                    'xcoord' : -88.2290526,
-                    'ycoord' :  40.1012122,
-                    'elevation' : 755,
-                    'input_crs':'EPSG:4326',#4269 is NAD83, defautling to WGS
-                    'output_crs':'EPSG:4326',
-                    'elev_unit' : 'feet',
-                    'depth' : 0,
-                    'instrument' : 'Raspberry Shake',
-                    'metapath' : '',
-                    'hvsr_band' : [0.4, 40],
-                    'write_path':'',
-                    'source':'file', 
-                    'export_format':'mseed', 
-                    'detrend':'spline', 
-                    'detrend_order':2, 
-                    'verbose':False}
-
-        print(f"\t{dataReadInfoDF.shape[0]} sites found: {list(dataReadInfoDF['site'])}")
-        if verbose:
-            maxLength = 25
-            maxColWidth = 12
-            if dataReadInfoDF.shape[0] > maxLength:
-                print(f'\t Showing information for first {maxLength} files only:')
-            print()
-            #Print nicely formated df
-            #Print column names
-            print('\t', end='')
-            for col in dataReadInfoDF.columns:
-                print(str(col)[:maxColWidth].ljust(maxColWidth), end='  ')
-            print('\n\t', end='')
-
-            #Print separator
-            tableLen = (maxColWidth+2)*len(dataReadInfoDF.columns)
-            for r in range(tableLen):
-                print('-', end='')
-            print()
-
-            #Print columns/rows
-            for index, row in dataReadInfoDF.iterrows():
-                print('\t', end='')
-                for col in row:
-                    if len(str(col)) > maxColWidth:
-                        print((str(col)[:maxColWidth-3]+'...').ljust(maxColWidth), end='  ')
-                    else:
-                        print(str(col)[:maxColWidth].ljust(maxColWidth), end='  ')
-                print()
-            if dataReadInfoDF.shape[0] > maxLength:
-                endline = f'\t...{dataReadInfoDF.shape[0]-maxLength} more rows in file.\n'
-            else:
-                endline = '\n'
-            print(endline)
-
-            print('Fetching the following files:')
-        param_dict_list = []
-        verboseStatement = []
-        if param_col is None: #Not a single parameter column, each col=parameter
-            for row_ind in range(dataReadInfoDF.shape[0]):
-                param_dict = {}
-                verboseStatement.append([])
-                for col in dataReadInfoDF.columns:
-                    if col in input_params_params or col in get_metadata_params or col in fetch_data_params:
-                        currParam = dataReadInfoDF.loc[row_ind, col]
-                        if pd.isna(currParam) or currParam == 'nan':
-                            if col in default_dict.keys():
-                                param_dict[col] = default_dict[col] #Get default value
-                                if verbose:
-                                    if type(default_dict[col]) is str:
-                                        verboseStatement[row_ind].append("\t\t'{}' parameter not specified in batch file. Using {}='{}'".format(col, col, default_dict[col]))
-                                    else:
-                                        verboseStatement[row_ind].append("\t\t'{}' parameter not specified in batch file. Using {}={}".format(col, col, default_dict[col]))
-                            else:
-                                param_dict[col] = None
-                        else:
-                            param_dict[col] = dataReadInfoDF.loc[row_ind, col]
-                param_dict_list.append(param_dict)
-        else:
-            if param_col not in dataReadInfoDF.columns:
-                raise IndexError('{} is not a column in {} (columns are: {})'.format(param_col, input_data, dataReadInfoDF.columns))
-            for row in dataReadInfoDF[param_col]:
-                param_dict = {}
-                splitRow = str(row).split(',')
-                for item in splitRow:
-                    param_dict[item.split('=')[0]] = item.split('=')[1]
-                param_dict_list.append(param_dict)
-        #input_params(datapath,site,network,station,loc,channels, acq_date,starttime, endtime, tzone, xcoord, ycoord, elevation, depth, instrument, metapath, hvsr_band)
-        #fetch_data(params, inv, source, trim_dir, export_format, detrend, detrend_order, verbose)
-        #get_metadata(params, write_path)
-    elif batch_type == 'filelist':
-        if isinstance(batch_params, list):
-            if len(batch_params) != len(input_data):
-                raise RuntimeError('If batch_params is list, it must be the same length as input_data. len(batch_params)={} != len(input_data)={}'.format(len(batch_params), len(input_data)))
-            param_dict_list = batch_params
-        elif isinstance(batch_params, dict):
-            batch_params.update(readcsv_getMeta_fetch_kwargs)
-            param_dict_list = []
-            for i in range(len(input_data)):
-                param_dict_list.append(batch_params)
-        
-        # Read and process each MiniSEED file
-        for i, file in enumerate(input_data):
-            if isinstance(file, obspy.core.stream.Stream):
-                warnings.warn('Reading in a list of Obspy streams is not currently supported, but may be implemented in the future', FutureWarning)
-                pass 
-            else:
-                param_dict_list[i]['datapath'] = file
-
-    hvsr_metaDict = {}
-    zfillDigs = len(str(len(param_dict_list))) #Get number of digits of length of param_dict_list
-    i=0
-    for i, param_dict in enumerate(param_dict_list):
-        # Read the data file into a Stream object
-        input_params_kwargs = {k: v for k, v in locals()['readcsv_getMeta_fetch_kwargs'].items() if k in input_params.__code__.co_varnames}
-        input_params_kwargs2 = {k: v for k, v in param_dict.items() if k in input_params.__code__.co_varnames}
-        input_params_kwargs.update(input_params_kwargs2)
-
-        params = input_params(**input_params_kwargs)
-
-        fetch_data_kwargs = {k: v for k, v in locals()['readcsv_getMeta_fetch_kwargs'].items() if k in fetch_data.__code__.co_varnames}
-        fetch_data_kwargs2 = {k: v for k, v in param_dict.items() if k in fetch_data.__code__.co_varnames[0:7]}
-        fetch_data_kwargs.update(fetch_data_kwargs2)
-        
-        try:
-            params = fetch_data(params=params, **fetch_data_kwargs)
-        except:
-            params['ProcessingStatus']['FetchDataStatus']=False
-            params['ProcessingStatus']['OverallStatus'] = False            
-        
-        if verbose and params['ProcessingStatus']['FetchDataStatus']:
-            print("\t  {}".format(params['site']))
-            if verboseStatement !=[]:
-                for item in verboseStatement[i]:
-                    print(item)
-        elif verbose and not params['ProcessingStatus']['FetchDataStatus']:
-            print("\t  {} not read correctly. Processing will not be carried out.".format(params['site']))
-                
-        params['batch'] = True
-
-        if params['site'] == default_dict['site']: #If site was not designated
-            params['site'] = "{}_{}".format(params['site'], str(i).zfill(zfillDigs))
-            i+=1
-        hvsr_metaDict[params['site']] = params
-
-    hvsr_metaDict = HVSRBatch(hvsr_metaDict)
-
-    return hvsr_metaDict
-
-
-
-def catch_errors(func) -
-
-
-
- -Expand source code - -
def catch_errors(func):
-    #Define a local function to get a list of warnings that we'll use in the output
-    def get_warning_msg_list(w):
-        messageList = []
-        #Collect warnings that happened before we got to the error
-        if w:
-            hasWarnings = True
-            for wi in w:
-                warning_category = type(wi.message).__name__.title().replace('warning','Warning')
-                #if w.line is None:
-                #    w.line = linecache.getline(wi.filename, wi.lineno)
-                warning_lineNo = wi.lineno
-                warning_message = str(wi.message)
-                # append the warning category and message to messageList so we get all warnings
-                messageList.append(f'{warning_category} ({warning_lineNo}): {warning_message}')
-        return messageList
-    
-    # use functools.wraps to preserve the original function's metadata
-    @functools.wraps(func)
-    def wrapper(*args, **kwargs):
-        result = None
-        # use the global keyword to access the error_message and error_category variables
-        global error_message
-        global error_category
-
-        messageList = []
-        hasWarnings = False
-        # use a try-except block to catch any exceptions
-        #result = func(*args, **kwargs)
-        try:
-            # use a context manager to catch any warnings
-            with warnings.catch_warnings(record=True) as w:
-                warnings.simplefilter('always')
-                # call the original function with the given arguments
-                result = func(*args, **kwargs)
-                
-                #Get message list, [] if no messages, doesn't run at all if Error/exception in func
-                messageList = get_warning_msg_list(w)
-                if messageList == []:
-                    return result
-                else:
-                    warningMessage = "WARNING:"
-                    for msg in messageList:
-                        warningMessage = "\n {}".format(msg)
-
-                    messagebox.showwarning(title='WARNINGS', message=warningMessage)
-                    
-        except Exception as e:
-            messageList = get_warning_msg_list(w)
-            errorObj = sys.exc_info()[2]
-
-            mainErrText = sys.exc_info()[1]
-
-            mainErrTb = traceback.extract_tb(sys.exc_info()[2])[-1]
-            mainErrFilePath = pathlib.Path(mainErrTb[0])
-            
-            mainErrFileName = mainErrFilePath.stem
-            mainErrLineNo = mainErrTb[1]
-            mainErrFunc = mainErrTb[2]
-            mainErrCodeLine = mainErrTb[3]
-
-            errLineNo1 = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
-            error_category = type(e).__name__.title().replace('error', 'Error')
-            error_message = f"{e} ({errLineNo1})"
-            
-            #Get message list, [] if no messages, doesn't run at all if Error/exception in func
-            warningMessageList = get_warning_msg_list(w)
-
-            #Build error messages
-            tbTuple0 = sys.exc_info()[0]
-            tbTuple1 = sys.exc_info()[1]
-            tbTuple2 = traceback.extract_tb(sys.exc_info()[2])
-            
-            logMsg = f"**ERROR**\n{tbTuple0.__name__}: {tbTuple1}"
-            dialogErrMsg = logMsg.split(':')[1]
-            for tb in tbTuple2:
-                logMsg = logMsg + '\n\t'
-                logMsg = logMsg + f"{pathlib.Path(tb[0]).stem}.{tb[2]}(): {tb[3]} (Line {tb[1]})"
-                dialogErrMsg = dialogErrMsg + f"\n{pathlib.Path(tb[0]).stem}.{tb[2]}(), Line {tb[1]}"
-            logMsg = logMsg + '\n\n'
-
-            #fullErrorMessage = f'ERROR {mainErrFileName}.{mainErrFunc} ({mainErrLineNo}): {mainErrText} \n\n {mainErrFileName} Line {mainErrLineNo}: {mainErrCodeLine}.'
-            if messageList == []:
-                pass
-            else:
-                dialogErrMsg = dialogErrMsg+"\n\n  Additional Warnings along the way. See Log for more information."
-                logMsg = logMsg + "\n\n\t  *WARNING(S)*\n\tAdditional Warnings along the way:"
-                for addMsg in warningMessageList:
-                    logMsg = logMsg+"\n\t\t{}".format(addMsg)
-            #print(dir(func))
-            #for i, keys in enumerate(dir(func)):
-            #    print(keys.upper(), func.__getattribute__(dir(func)[i]))
-
-
-            SPRIT_App.log_errorMsg(spritApp, logMsg)
-
-            messagebox.showerror(title=f'ERROR ({error_category})',
-                                    message=dialogErrMsg)
-            update_progress_bars(100)
-
-        # return the result of the function or the error/warning messages and categories
-        return result
-    # return the wrapper function
-    return wrapper
-
-
-
-def check_gui_requirements() -
-
-
-
- -Expand source code - -
def check_gui_requirements():
-    print("Checking requirements for gui")
-    # Define a command that tries to open a window
-    command = "python -c \"import tkinter; tkinter.Tk()\""
-
-    # Run the command and get the exit code
-    exit_code = os.system(command)
-    
-    # Check if tkinter gui could be created
-    if exit_code == 0:
-        #Tkinter 
-        oktoproceed=True
-    else:
-        oktoproceed=False
-        print("GUI window could not be created.")
-
-    return oktoproceed
-
-    #if sys.platform == 'linux':
-    #    # Check if qtwayland5 is installed
-    #    output = subprocess.run(["dpkg", "-s", "qtwayland5"], capture_output=True, text=True)
-    #    if "Status: install ok installed" in output.stdout:
-    #        print("qtwayland5 is already installed")
-    #    else:
-    #        print("qtwayland5 is not installed")
-    #        # Install qtwayland5
-    #        os.system("sudo apt install qtwayland5")
-
-
-
-def check_mark(incolor=False, interminal=False) -
-
-

The default Windows terminal is not able to display the check mark character correctly. -This function returns another displayable character if platform is Windows

-
- -Expand source code - -
def check_mark(incolor=False, interminal=False):
-    """The default Windows terminal is not able to display the check mark character correctly.
-       This function returns another displayable character if platform is Windows"""
-    if incolor:
-        try:
-            check = get_char(u'\u2705')
-        except:
-            check = get_char(u'\u2714')
-    else:
-        check = get_char(u'\u2714')
-
-    if sys.platform=='win32' and interminal:
-        check = get_char(u'\u039E')
-    return check
-
-
-
-def check_peaks(hvsr_data, hvsr_band=[0.4, 40], peak_freq_range=[1, 20], verbose=False) -
-
-

Function to run tests on HVSR peaks to find best one and see if it passes quality checks

-

Parameters

-
-
hvsr_data : dict
-
Dictionary containing all the calculated information about the HVSR data (i.e., hvsr_out returned from process_hvsr)
-
hvsr_band : tuple or list, default=[0.4, 40]
-
2-item tuple or list with lower and upper limit of frequencies to analyze
-
peak_freq_range : tuple or list, default=[1, 20];
-
The frequency range within which to check for peaks. If there is an HVSR curve with multiple peaks, this allows the full range of data to be processed while limiting peak picks to likely range.
-
verbose : bool, default=False
-
Whether to print results and inputs to terminal.
-
-

Returns

-
-
hvsr_data -: HVSRData or HVSRBatch object
-
Object containing previous input data, plus information about peak tests
-
-
- -Expand source code - -
def check_peaks(hvsr_data, hvsr_band=[0.4, 40], peak_freq_range=[1, 20], verbose=False):
-    """Function to run tests on HVSR peaks to find best one and see if it passes quality checks
-
-        Parameters
-        ----------
-        hvsr_data : dict
-            Dictionary containing all the calculated information about the HVSR data (i.e., hvsr_out returned from process_hvsr)
-        hvsr_band : tuple or list, default=[0.4, 40]
-            2-item tuple or list with lower and upper limit of frequencies to analyze
-        peak_freq_range : tuple or list, default=[1, 20];
-            The frequency range within which to check for peaks. If there is an HVSR curve with multiple peaks, this allows the full range of data to be processed while limiting peak picks to likely range.
-        verbose : bool, default=False
-            Whether to print results and inputs to terminal.
-        
-        Returns
-        -------
-        hvsr_data   : HVSRData or HVSRBatch object
-            Object containing previous input data, plus information about peak tests
-    """
-    orig_args = locals().copy() #Get the initial arguments
-
-    if (verbose and 'input_params' not in hvsr_data.keys()) or (verbose and not hvsr_data['batch']):
-        if isinstance(hvsr_data, HVSRData) and hvsr_data['batch']:
-            pass
-        else:
-            print('\nChecking peaks in the H/V Curve (check_peaks())')
-            print('\tUsing the following parameters:')
-            for key, value in orig_args.items():
-                if key=='hvsr_data':
-                    pass
-                else:
-                    print('\t  {}={}'.format(key, value))
-            print()
-  
-    #First, divide up for batch or not
-    if isinstance(hvsr_data, HVSRBatch):
-        if verbose:
-            print('\t  Running in batch mode')
-        #If running batch, we'll loop through each site
-        for site_name in hvsr_data.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            args['hvsr_data'] =  hvsr_data[site_name] #Get what would normally be the "params" variable for each site
-            if hvsr_data[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                    hvsr_data[site_name] = _check_peaks_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    if verbose:
-                        print(f"\t{site_name}: check_peaks() unsuccessful. Peaks not checked.")
-                    else:
-                        warnings.warn(f"\t{site_name}: check_peaks() unsuccessful. Peaks not checked.", RuntimeWarning)
-                
-        hvsr_data = HVSRBatch(hvsr_data)
-    else:
-        if hvsr_data['ProcessingStatus']['OverallStatus']:
-            if not hvsr_band:
-                hvsr_band = [0.4,40]
-            hvsr_data['hvsr_band'] = hvsr_band
-
-            anyK = list(hvsr_data['x_freqs'].keys())[0]
-
-            x = hvsr_data['x_freqs'][anyK] #Consistent for all curves
-            y = hvsr_data['hvsr_curve'] #Calculated based on "Use" column
-            index_list = hvsr_data['hvsr_peak_indices'] #Calculated based on hvsr_curve
-            hvsrp = hvsr_data['hvsrp'] #Calculated based on "Use" column
-            hvsrm = hvsr_data['hvsrm'] #Calculated based on "Use" column
-
-            hvsrPeaks = hvsr_data['hvsr_df'][hvsr_data['hvsr_df']['Use']]['CurvesPeakIndices']
-            #hvsrPeaks = hvsr_data['ind_hvsr_peak_indices'] #Original calculation
-
-            hvsr_log_std = hvsr_data['hvsr_log_std']
-            peak_freq_range = hvsr_data['peak_freq_range']
-
-            #Do for hvsr
-            peak = __init_peaks(x, y, index_list, hvsr_band, peak_freq_range)
-
-            peak = __check_curve_reliability(hvsr_data, peak)
-            peak = __check_clarity(x, y, peak, do_rank=True)
-
-            #Do for hvsrp
-            # Find  the relative extrema of hvsrp (hvsr + 1 standard deviation)
-            if not np.isnan(np.sum(hvsrp)):
-                index_p = __find_peaks(hvsrp)
-            else:
-                index_p = list()
-
-            peakp = __init_peaks(x, hvsrp, index_p, hvsr_band, peak_freq_range)
-            peakp = __check_clarity(x, hvsrp, peakp, do_rank=True)
-
-            #Do for hvsrm
-            # Find  the relative extrema of hvsrm (hvsr - 1 standard deviation)
-            if not np.isnan(np.sum(hvsrm)):
-                index_m = __find_peaks(hvsrm)
-            else:
-                index_m = list()
-
-            peakm = __init_peaks(x, hvsrm, index_m, hvsr_band, peak_freq_range)
-            peakm = __check_clarity(x, hvsrm, peakm, do_rank=True)
-
-            stdf = __get_stdf(x, index_list, hvsrPeaks)
-
-            peak = __check_freq_stability(peak, peakm, peakp)
-            peak = __check_stability(stdf, peak, hvsr_log_std, rank=True)
-
-            hvsr_data['Peak Report'] = peak
-
-            #Iterate through peaks and 
-            #   Get the BestPeak based on the peak score
-            #   Calculate whether each peak passes enough tests
-            curveTests = ['WindowLengthFreq.','SignificantCycles', 'LowCurveStDevOverTime']
-            peakTests = ['PeakFreqClarityBelow', 'PeakFreqClarityAbove', 'PeakAmpClarity', 'FreqStability', 'PeakStability_FreqStD', 'PeakStability_AmpStD']
-            bestPeakScore = 0
-
-            for p in hvsr_data['Peak Report']:
-                #Get BestPeak
-                if p['Score'] > bestPeakScore:
-                    bestPeakScore = p['Score']
-                    bestPeak = p
-
-                #Calculate if peak passes criteria
-                cTestsPass = 0
-                pTestsPass = 0
-                for testName in p['PassList'].keys():
-                    if testName in curveTests:
-                        if p['PassList'][testName]:
-                            cTestsPass += 1
-                    elif testName in peakTests:
-                        if p['PassList'][testName]:
-                            pTestsPass += 1
-
-                if cTestsPass == 3 and pTestsPass >= 5:
-                    p['PeakPasses'] = True
-                else:
-                    p['PeakPasses'] = False
-                
-            #Designate BestPeak in output dict
-            if len(hvsr_data['Peak Report']) == 0:
-                bestPeak={}
-                print(f"No Best Peak identified for {hvsr_data['site']}")
-
-            hvsr_data['BestPeak'] = bestPeak
-        else:
-            hvsr_data['BestPeak'] = {}
-            print(f"Processing Errors: No Best Peak identified for {hvsr_data['site']}")
-            
-    return hvsr_data
-
-
-
-def check_tsteps(hvsr_data) -
-
-

Check time steps of PPSDS to make sure they are all the same length

-
- -Expand source code - -
def check_tsteps(hvsr_data):
-    """Check time steps of PPSDS to make sure they are all the same length"""
-    ppsds = hvsr_data['ppsds']
-    tSteps = []
-    for k in ppsds.keys():
-        tSteps.append(np.array(ppsds[k]['psd_values']).shape[0])
-    if len(set(tSteps)) <= 1:
-        pass #This means all channels have same number of period_bin_centers
-        minTStep=tSteps[0]
-    else:
-        print('There is a different number of time-steps used to calculate HVSR curves. \n This may result in computational errors. Trimming longest.')
-        minTStep = min(tSteps)
-    return minTStep
-
-
-
-def check_xvalues(ppsds) -
-
-

Check x_values of PPSDS to make sure they are all the same length

-
- -Expand source code - -
def check_xvalues(ppsds):
-    """Check x_values of PPSDS to make sure they are all the same length"""
-    xLengths = []
-    for k in ppsds.keys():
-        xLengths.append(len(ppsds[k]['period_bin_centers']))
-    if len(set(xLengths)) <= 1:
-        pass #This means all channels have same number of period_bin_centers
-    else:
-        print('X-values (periods or frequencies) do not have the same values. \n This may result in computational errors')
-        #Do stuff to fix it?
-    return ppsds
-
-
-
-def checkifpath(filepath, sample_list='', verbose=False) -
-
-

Support function to check if a filepath is a pathlib.Path object and tries to convert if not

-

Parameters

-
-
filepath : str or pathlib.Path, or anything
-
Filepath to check. If not a valid filepath, will not convert and raises error
-
-

Returns

-
-
filepath : pathlib.Path
-
pathlib.Path of filepath
-
-
- -Expand source code - -
def checkifpath(filepath, sample_list='', verbose=False):
-    """Support function to check if a filepath is a pathlib.Path object and tries to convert if not
-
-    Parameters
-    ----------
-    filepath : str or pathlib.Path, or anything
-        Filepath to check. If not a valid filepath, will not convert and raises error
-
-    Returns
-    -------
-    filepath : pathlib.Path
-        pathlib.Path of filepath
-    """
-    if sample_list=='':
-        sample_list = ['1', '2', '3', '4', '5', '6', 'sample', 'batch', 'sample', 'sample_batch']
-        for s in range(1, 7):
-            sample_list.append(f"sample{s}")
-            sample_list.append(f"sample_{s}")
-
-    # checks if the variable is any instance of pathlib
-    if isinstance(filepath, pathlib.PurePath):
-        pass
-    elif str(filepath) in sample_list:
-        pass
-    else:
-        try:
-            filepath = pathlib.Path(filepath)
-        except:
-            if verbose:
-                warnings.warn('Filepath cannot be converted to pathlib path: {}'.format(filepath))
-        if not filepath.exists():
-            raise RuntimeError('File does not exist: {}'.format(filepath))
-    return filepath
-
-
-
-def export_data(hvsr_data, export_path=None, ext='hvsr', verbose=False) -
-
-

Export data into pickle format that can be read back in using import_data() so data does not need to be processed each time. -Default extension is .hvsr but it is still a pickled file that can be read in using pickle.load().

-

Parameters

-
-
hvsr_data : HVSRData or HVSRBatch
-
Data to be exported
-
export_path : str or filepath object, default = None
-
String or filepath object to be read by pathlib.Path() and/or a with open(export_path, 'wb') statement. If None, defaults to input datapath directory, by default None
-
ext : str, default = 'hvsr'
-
Filepath extension to use for data file, by default 'hvsr'
-
-
- -Expand source code - -
def export_data(hvsr_data, export_path=None, ext='hvsr', verbose=False):
-    """Export data into pickle format that can be read back in using import_data() so data does not need to be processed each time. 
-    Default extension is .hvsr but it is still a pickled file that can be read in using pickle.load().
-
-    Parameters
-    ----------
-    hvsr_data : HVSRData or HVSRBatch
-        Data to be exported
-    export_path : str or filepath object, default = None
-        String or filepath object to be read by pathlib.Path() and/or a with open(export_path, 'wb') statement. If None, defaults to input datapath directory, by default None
-    ext : str, default = 'hvsr'
-        Filepath extension to use for data file, by default 'hvsr'
-    """
-    def _do_export(_hvsr_data=hvsr_data, _export_path=export_path, _ext=ext):
-        
-        fname = f"{_hvsr_data.site}_{_hvsr_data.acq_date}_pickled.{ext}"
-        if _export_path is None or _export_path is True:
-            _export_path = _hvsr_data['datapath']
-            _export_path = pathlib.Path(_export_path).with_name(fname)
-        else:
-            _export_path = pathlib.Path(_export_path)
-            if _export_path.is_dir():
-                _export_path = _export_path.joinpath(fname)    
-
-        _export_path = str(_export_path)
-        with open(_export_path, 'wb') as f:
-            pickle.dump(_hvsr_data, f) 
-            
-        if verbose:
-            print(f"Processed data exported as pickled data to: {_export_path} [~{round(float(pathlib.Path(_export_path).stat().st_size)/2**20,1)} Mb]")    
-            
-    if isinstance(hvsr_data, HVSRBatch):
-        for sitename in hvsr_data.keys():
-            _do_export(hvsr_data[sitename], export_path, ext)
-    elif isinstance(hvsr_data, HVSRData):
-        _do_export(hvsr_data, export_path, ext)
-    else:
-        print("Error in data export. Data must be either of type sprit.HVSRData or sprit.HVSRBatch")         
-    return
-
-
-
-def fetch_data(params, inv=None, source='file', trim_dir=None, export_format='mseed', detrend='spline', detrend_order=2, update_metadata=True, plot_input_stream=False, verbose=False, **kwargs) -
-
-
-
- -Expand source code - -
def fetch_data(params, inv=None, source='file', trim_dir=None, export_format='mseed', detrend='spline', detrend_order=2, update_metadata=True, plot_input_stream=False, verbose=False, **kwargs):
-    import warnings
-
-    """Fetch ambient seismic data from a source to read into obspy stream
-        
-        Parameters
-        ----------
-        params  : dict
-            Dictionary containing all the necessary params to get data.
-                Parameters defined using input_params() function.
-        inv     : obspy inventory object, default=None
-            Obspy inventory object containing metadata for instrument that collected data to be fetched. By default, the inventory object is read from params['inv'], but this can be manually specified here too.
-        source  : str, {'raw', 'dir', 'file', 'batch'}
-            String indicating where/how data file was created. For example, if raw data, will need to find correct channels.
-                'raw' finds raspberry shake data, from raw output copied using scp directly from Raspberry Shake, either in folder or subfolders; 
-                'dir' is used if the day's 3 component files (currently Raspberry Shake supported only) are all 3 contained in a directory by themselves.
-                'file' is used if the params['datapath'] specified in input_params() is the direct filepath to a single file to be read directly into an obspy stream.
-                'batch' is used to read a list or specified set of seismic files. 
-                    Most commonly, a csv file can be read in with all the parameters. Each row in the csv is a separate file. Columns can be arranged by parameter.
-        trim_dir : None or str or pathlib obj, default=None
-            If None (or False), data is not trimmed in this function.
-            Otherwise, this is the directory to save trimmed and exported data.
-        export_format: str='mseed'
-            If trim_dir is not False, this is the format in which to save the data
-        detrend : str or bool, default='spline'
-            If False, data is not detrended.
-            Otherwise, this should be a string accepted by the type parameter of the obspy.core.trace.Trace.detrend method: https://docs.obspy.org/packages/autogen/obspy.core.trace.Trace.detrend.html
-        detrend_order : int, default=2
-            If detrend parameter is 'spline' or 'polynomial', this is passed directly to the order parameter of obspy.core.trace.Trace.detrend method.
-        update_metadata : bool, default=True
-            Whether to update the metadata file, used primarily with Raspberry Shake data which uses a generic inventory file.
-        plot_input_stream : bool, default=False
-            Whether to plot the raw input stream. This plot includes a spectrogram (Z component) and the raw (with decimation for speed) plots of each component signal.
-        verbose : bool, default=False
-            Whether to print outputs and inputs to the terminal
-        **kwargs
-            Keywords arguments, primarily for 'batch' and 'dir' sources
-            
-        Returns
-        -------
-        params : HVSRData or HVSRBatch object
-            Same as params parameter, but with an additional "stream" attribute with an obspy data stream with 3 traces: Z (vertical), N (North-south), and E (East-west)
-        """
-    if source != 'batch' and verbose:
-        print('\nFetching data (fetch_data())')
-        print()
-
-    params = get_metadata(params, update_metadata=update_metadata, source=source)
-    inv = params['inv']
-    date=params['acq_date']
-
-    #Cleanup for gui input
-    if '}' in str(params['datapath']):
-        params['datapath'] = params['datapath'].as_posix().replace('{','')
-        params['datapath'] = params['datapath'].split('}')
-    
-    sampleListNos = ['1', '2', '3', '4', '5', '6']
-    sampleList = ['1', '2', '3', '4', '5', '6', 'batch', 'sample', 'sample_batch']
-    for s in sampleListNos:
-        sampleList.append(f'sample{s}')
-        sampleList.append(f'sample_{s}')
-
-    #Make sure datapath is pointing to an actual file
-    if isinstance(params['datapath'],list):
-        for i, d in enumerate(params['datapath']):
-            params['datapath'][i] = sprit_utils.checkifpath(str(d).strip())
-    else:
-        dPath = sprit_utils.checkifpath(params['datapath'], sample_list=sampleList)
-
-    inst = params['instrument']
-
-    #Need to put dates and times in right formats first
-    if type(date) is datetime.datetime:
-        doy = date.timetuple().tm_yday
-        year = date.year
-    elif type(date) is datetime.date:
-        date = datetime.datetime.combine(date, datetime.time(hour=0, minute=0, second=0))
-        doy = date.timetuple().tm_yday
-        year = date.year
-    elif type(date) is tuple:
-        if date[0]>366:
-            raise ValueError('First item in date tuple must be day of year (0-366)', 0)
-        elif date[1] > datetime.datetime.now().year:
-            raise ValueError('Second item in date tuple should be year, but given item is in the future', 0)
-        else:
-            doy = date[0]
-            year = date[1]
-    elif type(date) is str:
-        if '/' in date:
-            dateSplit = date.split('/')            
-        elif '-' in date:
-            dateSplit = date.split('-')
-        else:
-            dateSplit = date
-
-        if int(dateSplit[0]) > 31:
-            date = datetime.datetime(int(dateSplit[0]), int(dateSplit[1]), int(dateSplit[2]))
-            doy = date.timetuple().tm_yday
-            year = date.year
-        elif int(dateSplit[0])<=12 and int(dateSplit[2]) > 31:
-            warnings.warn("Preferred date format is 'yyyy-mm-dd' or 'yyyy/mm/dd'. Will attempt to parse date.")
-            date = datetime.datetime(int(dateSplit[2]), int(dateSplit[0]), int(dateSplit[1]))
-            doy = date.timetuple().tm_yday
-            year = date.year
-        else:
-            warnings.warn("Preferred date format is 'yyyy-mm-dd' or 'yyyy/mm/dd'. Cannot parse date.")
-    elif type(date) is int:
-        doy = date
-        year = datetime.datetime.today().year
-    else: #FOR NOW, need to update
-        date = datetime.datetime.now()
-        doy = date.timetuple().tm_yday
-        year = date.year
-        warnings.warn("Did not recognize date, using year {} and day {}".format(year, doy))
-
-    #Select which instrument we are reading from (requires different processes for each instrument)
-    raspShakeInstNameList = ['raspberry shake', 'shake', 'raspberry', 'rs', 'rs3d', 'rasp. shake', 'raspshake']
-
-    #Select how reading will be done
-    if source=='raw':
-        if inst.lower() in raspShakeInstNameList:
-            try:
-                rawDataIN = __read_RS_file_struct(dPath, source, year, doy, inv, params, verbose=verbose)
-            except:
-                raise RuntimeError(f"Data not fetched for {params['site']}. Check input parameters or the data file.")
-                return params
-    elif source=='dir':
-        if inst.lower() in raspShakeInstNameList:
-            rawDataIN = __read_RS_file_struct(dPath, source, year, doy, inv, params, verbose=verbose)
-        else:
-            obspyFiles = {}
-            for obForm in obspyFormats:
-                temp_file_glob = pathlib.Path(dPath.as_posix().lower()).glob('.'+obForm.lower())
-                for f in temp_file_glob:
-                    currParams = params
-                    currParams['datapath'] = f
-                    curr_data = fetch_data(params, source='file', #all the same as input, except just reading the one file using the source='file'
-                                trim_dir=trim_dir, export_format=export_format, detrend=detrend, detrend_order=detrend_order, update_metadata=update_metadata, verbose=verbose, **kwargs), 
-                    obspyFiles[f.stem] = curr_data  #Add path object to dict, with filepath's stem as the site name
-            return HVSRBatch(obspyFiles)
-        
-    elif source=='file' and str(params['datapath']).lower() not in sampleList:
-        if isinstance(dPath, list) or isinstance(dPath, tuple):
-            rawStreams = []
-            for datafile in dPath:
-                rawStream = obspy.read(datafile)
-                rawStreams.append(rawStream) #These are actually streams, not traces
-            
-            for i, stream in enumerate(rawStreams):
-                if i == 0:
-                    rawDataIN = obspy.Stream(stream) #Just in case
-                else:
-                    rawDataIN = rawDataIN + stream #This adds a stream/trace to the current stream object
-            
-        elif str(dPath)[:6].lower()=='sample':
-            pass
-        else:
-            rawDataIN = obspy.read(dPath)#, starttime=obspy.core.UTCDateTime(params['starttime']), endttime=obspy.core.UTCDateTime(params['endtime']), nearest_sample =True)
-        import warnings
-        with warnings.catch_warnings():
-            warnings.simplefilter(action='ignore', category=UserWarning)
-            rawDataIN.attach_response(inv)
-    elif source=='batch' and str(params['datapath']).lower() not in sampleList:
-        if verbose:
-            print('\nFetching data (fetch_data())')
-        batch_data_read_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in batch_data_read.__code__.co_varnames}
-        params = batch_data_read(input_data=params['datapath'], verbose=verbose, **batch_data_read_kwargs)
-        params = HVSRBatch(params)
-        return params
-    elif str(params['datapath']).lower() in sampleList or f"sample{params['datapath'].lower()}" in sampleList:
-        sample_data_dir = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/sample_data/'))
-        if source=='batch':
-            params['datapath'] = sample_data_dir.joinpath('Batch_SampleData.csv')
-            params = batch_data_read(input_data=params['datapath'], batch_type='sample', verbose=verbose)
-            params = HVSRBatch(params)
-            return params
-
-        elif source=='dir':
-            params['datapath'] = sample_data_dir.joinpath('Batch_SampleData.csv')
-            params = batch_data_read(input_data=params['datapath'], batch_type='sample', verbose=verbose)
-            params = HVSRBatch(params)
-            return params
-
-        elif source=='file':
-            params['datapath'] = str(params['datapath']).lower()
-            
-            if params['datapath'].lower() in sampleFileKeyMap.keys():
-                params['datapath'] = sampleFileKeyMap[params['datapath'].lower()]
-            else:
-                params['datapath'] = sample_data_dir.joinpath('SampleHVSRSite1_AM.RAC84.00.2023.046_2023-02-15_1704-1734.MSEED')
-
-            dPath = params['datapath']
-            rawDataIN = obspy.read(dPath)#, starttime=obspy.core.UTCDateTime(params['starttime']), endttime=obspy.core.UTCDateTime(params['endtime']), nearest_sample =True)
-            import warnings
-            with warnings.catch_warnings():
-                warnings.simplefilter(action='ignore', category=UserWarning)
-                rawDataIN.attach_response(inv)
-    else:
-        try:
-            rawDataIN = obspy.read(dPath)
-            rawDataIN.attach_response(inv)
-        except:
-            RuntimeError(f'source={source} not recognized, and datapath cannot be read using obspy.read()')
-
-    try:
-        dataIN = rawDataIN.copy()
-        if source!='raw':
-            #Use metadata from file for;
-            # site
-            if params['site'] == "HVSR Site":
-                params['site'] = dPath.stem
-                params['params']['site'] = dPath.stem
-            
-            # network
-            if str(params['net']) == 'AM':
-                params['net'] = dataIN[0].stats.network
-                params['params']['net'] = dataIN[0].stats.network
-
-            # station
-            if str(params['sta']) == 'RAC84':
-                params['sta'] = dataIN[0].stats.station
-                params['params']['sta'] = dataIN[0].stats.station
-
-            # loc
-            if str(params['loc']) == '00':
-                params['loc'] = dataIN[0].stats.location
-                params['params']['loc'] = dataIN[0].stats.location
-            
-            # channels
-            channelList = []
-            if str(params['cha']) == ['EHZ', 'EHN', 'EHE']:
-                for tr in dataIN:
-                    if tr.stats.channel not in channelList:
-                        channelList.append(tr.stats.channel)
-                        channelList.sort(reverse=True) #Just so z is first, just in case
-                params['cha'] = channelList
-                params['params']['cha'] = channelList
-           
-            # Acquisition date
-            if str(params['acq_date']) == str(datetime.datetime.now().date()):
-                params['acq_date'] = dataIN[0].stats.starttime.date
-
-            # starttime
-            today_Starttime = obspy.UTCDateTime(datetime.datetime(year=datetime.date.today().year, month=datetime.date.today().month,
-                                                                 day = datetime.date.today().day,
-                                                                hour=0, minute=0, second=0, microsecond=0))
-            maxStarttime = datetime.time(hour=0, minute=0, second=0, microsecond=0)
-            if str(params['starttime']) == str(today_Starttime):
-                for tr in dataIN.merge():
-                    currTime = datetime.time(hour=tr.stats.starttime.hour, minute=tr.stats.starttime.minute, 
-                                       second=tr.stats.starttime.second, microsecond=tr.stats.starttime.microsecond)
-                    if currTime > maxStarttime:
-                        maxStarttime = currTime
-
-                newStarttime = obspy.UTCDateTime(datetime.datetime(year=params['acq_date'].year, month=params['acq_date'].month,
-                                                                 day = params['acq_date'].day,
-                                                                hour=maxStarttime.hour, minute=maxStarttime.minute, 
-                                                                second=maxStarttime.second, microsecond=maxStarttime.microsecond))
-                params['starttime'] = newStarttime
-                params['params']['starttime'] = newStarttime
-
-            # endttime
-            today_Endtime = obspy.UTCDateTime(datetime.datetime(year=datetime.date.today().year, month=datetime.date.today().month,
-                                                                 day = datetime.date.today().day,
-                                                                hour=23, minute=59, second=59, microsecond=999999))
-            minEndtime = datetime.time(hour=23, minute=59, second=59, microsecond=999999)
-            if str(params['endtime']) == str(today_Endtime):
-                for tr in dataIN.merge():
-                    currTime = datetime.time(hour=tr.stats.endtime.hour, minute=tr.stats.endtime.minute, 
-                                       second=tr.stats.endtime.second, microsecond=tr.stats.endtime.microsecond)
-                    if currTime < minEndtime:
-                        minEndtime = currTime
-                newEndtime = obspy.UTCDateTime(datetime.datetime(year=params['acq_date'].year, month=params['acq_date'].month,
-                                                                 day = params['acq_date'].day,
-                                                                hour=minEndtime.hour, minute=minEndtime.minute, 
-                                                                second=minEndtime.second, microsecond=minEndtime.microsecond))
-                params['endtime'] = newEndtime
-                params['params']['endtime'] = newEndtime
-
-
-            #print(dataIN)
-            #print(params['starttime'])
-            #print(params['endtime'])
-            dataIN = dataIN.split()
-            dataIN = dataIN.trim(starttime=params['starttime'], endtime=params['endtime'])
-            dataIN.merge()
-            #print(dataIN)
-    except:
-        raise RuntimeError('Data not fetched. Check your input parameters or the data file.')
-        
-    #Trim and save data as specified
-    if not trim_dir:
-        pass
-    else:
-        if isinstance(params, HVSRBatch):
-            pass
-        else:
-            dataIN = _trim_data(input=params, stream=dataIN, export_dir=trim_dir, source=source, export_format=export_format)
-
-    #Split data if masked array (if there are gaps)...detrending cannot be done without
-    for tr in dataIN:
-        if isinstance(tr.data, np.ma.masked_array):
-            dataIN = dataIN.split()
-            #Splits entire stream if any trace is masked_array
-            break
-
-    #Detrend data
-    if isinstance(params, HVSRBatch):
-        pass
-    else:
-        dataIN =  __detrend_data(input=dataIN, detrend=detrend, detrend_order=detrend_order, verbose=verbose, source=source)
-
-    #Remerge data
-    dataIN = dataIN.merge(method=1)
-
-    if plot_input_stream:
-        #dataIN.plot(method='full', linewidth=0.25)
-        params['InputPlot'] = _plot_specgram_stream(stream=dataIN, params=params, component='Z', stack_type='linear', detrend='mean', dbscale=True, fill_gaps=None, ylimstd=3, return_fig=True, fig=None, ax=None, show_plot=False)
-        _get_removed_windows(input=dataIN, fig=params['InputPlot'][0], ax=params['InputPlot'][1], lineArtist =[], winArtist = [], existing_lineArtists=[], existing_xWindows=[], exist_win_format='matplotlib', keep_line_artists=True, time_type='matplotlib', show_plot=True)
-
-        #Sort channels (make sure Z is first, makes things easier later)
-    if isinstance(params, HVSRBatch):
-        pass
-    else:
-        dataIN = _sort_channels(input=dataIN, source=source, verbose=verbose)
-
-    if 'clean_ends' not in kwargs.keys():
-        clean_ends=True 
-    else:
-        clean_ends = kwargs['clean_ends']
-
-    if clean_ends:
-        maxStarttime = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) - datetime.timedelta(days=36500) #100 years ago
-        minEndtime = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) 
-
-        for tr in dataIN:
-            currStarttime = datetime.datetime(year=tr.stats.starttime.year, month=tr.stats.starttime.month, day=tr.stats.starttime.day, 
-                                         hour=tr.stats.starttime.hour, minute=tr.stats.starttime.minute, 
-                                         second=tr.stats.starttime.second, microsecond=tr.stats.starttime.microsecond, tzinfo=datetime.timezone.utc)
-            if currStarttime > maxStarttime:
-                maxStarttime = currStarttime
-
-            currEndtime = datetime.datetime(year=tr.stats.endtime.year, month=tr.stats.endtime.month, day=tr.stats.endtime.day, 
-                                         hour=tr.stats.endtime.hour, minute=tr.stats.endtime.minute, 
-                                         second=tr.stats.endtime.second, microsecond=tr.stats.endtime.microsecond, tzinfo=datetime.timezone.utc)
-
-            if currEndtime < minEndtime:
-                minEndtime = currEndtime
-
-
-        maxStarttime = obspy.UTCDateTime(maxStarttime)
-        minEndtime = obspy.UTCDateTime(minEndtime)
-        dataIN = dataIN.split()
-        for tr in dataIN:
-            tr.trim(starttime=maxStarttime, endtime=minEndtime)
-            pass
-        dataIN.merge()
-    
-    params['batch'] = False #Set False by default, will get corrected later in batch mode        
-    params['input_stream'] = dataIN
-    params['stream'] = dataIN.copy()
-    params['ProcessingStatus']['FetchDataStatus'] = True
-    if verbose and not isinstance(params, HVSRBatch):
-        dataINStr = dataIN.__str__().split('\n')
-        for line in dataINStr:
-            print('\t',line)
-    
-    params = _check_processing_status(params)
-
-    return params
-
-
-
-def format_time(inputDT, tzone='UTC') -
-
-

Private function to format time, used in other functions

-

Formats input time to datetime objects in utc

-

Parameters

-
-
inputDT : str or datetime obj
-
Input datetime. Can include date and time, just date (time inferred to be 00:00:00.00) or just time (if so, date is set as today)
-
-

tzone -: str='utc' or int {'utc', 'local'} -Timezone of data entry. -If string and not utc, assumed to be timezone of computer running the process. -If int, assumed to be offset from UTC (e.g., CST in the United States is -6; CDT in the United States is -5)

-

Returns

-
-
outputTimeObj : datetime object in UTC
-
Output datetime.datetime object, now in UTC time.
-
-
- -Expand source code - -
def format_time(inputDT, tzone='UTC'):
-    """Private function to format time, used in other functions
-
-    Formats input time to datetime objects in utc
-
-    Parameters
-    ----------
-    inputDT : str or datetime obj 
-        Input datetime. Can include date and time, just date (time inferred to be 00:00:00.00) or just time (if so, date is set as today)
-    tzone   : str='utc' or int {'utc', 'local'} 
-        Timezone of data entry. 
-            If string and not utc, assumed to be timezone of computer running the process.
-            If int, assumed to be offset from UTC (e.g., CST in the United States is -6; CDT in the United States is -5)
-
-    Returns
-    -------
-    outputTimeObj : datetime object in UTC
-        Output datetime.datetime object, now in UTC time.
-
-    """
-    if type(inputDT) is str:
-        #tzone = 'America/Chicago'
-        #Format string to datetime obj
-        div = '-'
-        timeDiv = 'T'
-        if "/" in inputDT:
-            div = '/'
-            hasDate = True
-        elif '-' in inputDT:
-            div = '-'
-            hasDate = True
-        else:
-            hasDate= False
-            year = datetime.datetime.today().year
-            month = datetime.datetime.today().month
-            day = datetime.datetime.today().day
-
-        if ':' in inputDT:
-            hasTime = True
-            if 'T' in inputDT:
-                timeDiv = 'T'
-            else:
-                timeDiv = ' '
-        else:
-            hasTime = False
-        
-        if hasDate:
-            #If first number is 4-dig year (assumes yyyy-dd-mm is not possible)
-            if len(inputDT.split(div)[0])>2:
-                year = inputDT.split(div)[0]
-                month = inputDT.split(div)[1]
-                day = inputDT.split(div)[2].split(timeDiv)[0]
-
-            #If last number is 4-dig year            
-            elif len(inputDT.split(div)[2].split(timeDiv)[0])>2:
-                #..and first number is day
-                if int(inputDT.split(div)[0])>12:
-                    #dateStr = '%d'+div+'%m'+div+'%Y'   
-                    year = inputDT.split(div)[2].split(timeDiv)[0]
-                    month = inputDT.split(div)[1]
-                    day = inputDT.split(div)[0]
-                #...and first number is month (like American style)                             
-                else:
-                    year = inputDT.split(div)[2].split(timeDiv)[0]
-                    month = inputDT.split(div)[0]
-                    day = inputDT.split(div)[1]     
-            
-            #Another way to catch if first number is (2-digit) year
-            elif int(inputDT.split(div)[0])>31:
-                #dateStr = '%y'+div+'%m'+div+'%d'
-                year = inputDT.split(div)[0]
-                #Assumes anything less than current year is from this century
-                if year < datetime.datetime.today().year:
-                    year = '20'+year
-                else:#...and anything more than current year is from last century
-                    year = '19'+year
-                #assumes day will always come last in this instance, as above
-                month = inputDT.split(div)[1]
-                day = inputDT.split(div)[2].split(timeDiv)[0]
-
-            #If last digit is (2 digit) year           
-            elif int(inputDT.split(div)[2].split(timeDiv)[0])>31:
-                #...and first digit is day
-                if int(inputDT.split(div)[0])>12:
-                    #dateStr = '%d'+div+'%m'+div+'%y'       
-                    year = inputDT.split(div)[2].split(timeDiv)[0]
-                    if year < datetime.datetime.today().year:
-                        year = '20'+year
-                    else:
-                        year = '19'+year
-                    month = inputDT.split(div)[1]
-                    day = inputDT.split(div)[0]                           
-                else: #...and second digit is day
-                    #dateStr = '%m'+div+'%d'+div+'%y'
-                    year = inputDT.split(div)[2].split(timeDiv)[0]
-                    if year < datetime.datetime.today().year:
-                        year = '20'+year
-                    else:
-                        year = '19'+year
-                    month = inputDT.split(div)[0]
-                    day = inputDT.split(div)[1]                  
-
-        hour=0
-        minute=0
-        sec=0
-        microS=0
-        if hasTime:
-            if hasDate:
-                timeStr = inputDT.split(timeDiv)[1]
-            else:
-                timeStr = inputDT
-            
-            if 'T' in timeStr:
-                timeStr=timeStr.split('T')[1]
-            elif ' ' in timeStr:
-                timeStr=timeStr.split(' ')[1]
-
-            timeStrList = timeStr.split(':')
-            if len(timeStrList[0])>2:
-                timeStrList[0] = timeStrList[0][-2:]
-            elif int(timeStrList[0]) > 23:
-                timeStrList[0] = timeStrList[0][-1:]
-            
-            if len(timeStrList) == 3:
-                if '.' in timeStrList[2]:
-                    microS = int(timeStrList[2].split('.')[1])
-                    timeStrList[2] = timeStrList[2].split('.')[0]
-            elif len(timeStrList) == 2:
-                timeStrList.append('00')
-
-            hour = int(timeStrList[0])
-            minute=int(timeStrList[1])
-            sec = int(timeStrList[2])
-
-        outputTimeObj = datetime.datetime(year=int(year),month=int(month), day=int(day),
-                                hour=int(hour), minute=int(minute), second=int(sec), microsecond=int(microS))
-
-    elif type(inputDT) is datetime.datetime or type(inputDT) is datetime.time:
-        outputTimeObj = inputDT
-
-    #Add timezone info
-    availableTimezones = list(map(str.lower, zoneinfo.available_timezones()))
-    if outputTimeObj.tzinfo is not None and outputTimeObj.tzinfo.utcoffset(outputTimeObj) is not None:
-        #This is already timezone aware
-        pass
-    elif type(tzone) is int:
-        outputTimeObj = outputTimeObj-datetime.timedelta(hours=tzone)
-    elif type(tzone) is str:
-        if tzone.lower() in availableTimezones:
-            outputTimeObj = outputTimeObj.replace(tzinfo=zoneinfo.ZoneInfo(tzone))
-        else:
-            raise ValueError("Timezone {} is not in official list. \nAvailable timezones:\n{}".format(tzone, availableTimezones))
-    elif isinstance(tzone, zoneinfo.ZoneInfo):
-        outputTimeObj = outputTimeObj.replace(tzinfo=tzone)
-    else:
-        raise ValueError("Timezone must be either str or int")
-    
-    #Convert to UTC
-    outputTimeObj = outputTimeObj.astimezone(datetime.timezone.utc)   
-
-    return outputTimeObj
-
-
-
-def generate_ppsds(params, remove_outliers=True, outlier_std=3, verbose=False, **ppsd_kwargs) -
-
-

Generates PPSDs for each channel

-

Channels need to be in Z, N, E order -Info on PPSD creation here: https://docs.obspy.org/packages/autogen/obspy.signal.spectral_estimation.PPSD.html

-

Parameters

-
-
params : dict, HVSRData object, or HVSRBatch object
-
Data object containing all the parameters and other data of interest (stream and paz, for example)
-
remove_outliers : bool, default=True
-
Whether to remove outlier h/v curves. This is recommended, particularly if remove_noise() has been used.
-
outlier_std :  float, default=3
-
The standard deviation value to use as a threshold for determining whether a curve is an outlier. -This averages over the entire curve so that curves with very abberant data (often occurs when using the remove_noise() method), can be identified.
-
verbose : bool, default=True
-
Whether to print inputs and results to terminal
-
**ppsd_kwargs : dict
-
Dictionary with keyword arguments that are passed directly to obspy.signal.PPSD. -If the following keywords are not specified, their defaults are amended in this function from the obspy defaults for its PPSD function. Specifically: -- ppsd_length defaults to 60 (seconds) here instead of 3600 -- skip_on_gaps defaults to True instead of False -- period_step_octaves defaults to 0.03125 instead of 0.125
-
-

Returns

-
ppsds : HVSRData object
-    Dictionary containing entries with ppsds for each channel
-
-
- -Expand source code - -
def generate_ppsds(params, remove_outliers=True, outlier_std=3, verbose=False, **ppsd_kwargs):
-    """Generates PPSDs for each channel
-
-        Channels need to be in Z, N, E order
-        Info on PPSD creation here: https://docs.obspy.org/packages/autogen/obspy.signal.spectral_estimation.PPSD.html
-        
-        Parameters
-        ----------
-        params : dict, HVSRData object, or HVSRBatch object
-            Data object containing all the parameters and other data of interest (stream and paz, for example)
-        remove_outliers : bool, default=True
-            Whether to remove outlier h/v curves. This is recommended, particularly if remove_noise() has been used.
-        outlier_std :  float, default=3
-            The standard deviation value to use as a threshold for determining whether a curve is an outlier. 
-            This averages over the entire curve so that curves with very abberant data (often occurs when using the remove_noise() method), can be identified.
-        verbose : bool, default=True
-            Whether to print inputs and results to terminal
-        **ppsd_kwargs : dict
-            Dictionary with keyword arguments that are passed directly to obspy.signal.PPSD.
-            If the following keywords are not specified, their defaults are amended in this function from the obspy defaults for its PPSD function. Specifically:
-                - ppsd_length defaults to 60 (seconds) here instead of 3600
-                - skip_on_gaps defaults to True instead of False
-                - period_step_octaves defaults to 0.03125 instead of 0.125
-
-        Returns
-        -------
-            ppsds : HVSRData object
-                Dictionary containing entries with ppsds for each channel
-    """
-    #First, divide up for batch or not
-    orig_args = locals().copy() #Get the initial arguments
-
-    ppsd_kwargs_sprit_defaults = ppsd_kwargs.copy()
-    #Set defaults here that are different than obspy defaults
-    if 'ppsd_length' not in ppsd_kwargs:
-        ppsd_kwargs_sprit_defaults['ppsd_length'] = 30.0
-    if 'skip_on_gaps' not in ppsd_kwargs:
-        ppsd_kwargs_sprit_defaults['skip_on_gaps'] = True
-    if 'period_step_octaves' not in ppsd_kwargs:
-        ppsd_kwargs_sprit_defaults['period_step_octaves'] = 0.03125
-
-    #Get Probablistic power spectral densities (PPSDs)
-    #Get default args for function
-    def get_default_args(func):
-        signature = inspect.signature(func)
-        return {
-            k: v.default
-            for k, v in signature.parameters.items()
-            if v.default is not inspect.Parameter.empty
-            }
-    
-    ppsd_kwargs = get_default_args(PPSD)
-    ppsd_kwargs.update(ppsd_kwargs_sprit_defaults)#Update with sprit defaults, or user input
-
-    orig_args['ppsd_kwargs'] = [ppsd_kwargs]
-
-    if (verbose and isinstance(params, HVSRBatch)) or (verbose and not params['batch']):
-        if isinstance(params, HVSRData) and params['batch']:
-            pass
-        else:
-            print('\nGenerating Probabilistic Power Spectral Densities (generate_ppsds())')
-            print('\tUsing the following parameters:')
-            for key, value in orig_args.items():
-                if key=='params':
-                    pass
-                else:
-                    print('\t  {}={}'.format(key, value))
-            print()
-    
-    #Site is in the keys anytime it's not batch
-    if isinstance(params, HVSRBatch):
-        #If running batch, we'll loop through each one
-        for site_name in params.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            individual_params = params[site_name] #Get what would normally be the "params" variable for each site
-            args['params'] = individual_params #reset the params parameter we originally read in to an individual site params
-            #args['params']['batch'] = False #Set to false, since only running this time
-            if params[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                    params[site_name] = _generate_ppsds_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    params[site_name]['ProcessingStatus']['PPSDStatus']=False
-                    params[site_name]['ProcessingStatus']['OverallStatus'] = False                     
-            else:
-                params[site_name]['ProcessingStatus']['PPSDStatus']=False
-                params[site_name]['ProcessingStatus']['OverallStatus'] = False                
-        return params
-    else:
-        paz=params['paz']
-        stream = params['stream']
-
-        #Get ppsds of e component
-        eStream = stream.select(component='E')
-        estats = eStream.traces[0].stats
-        ppsdE = PPSD(estats, paz['E'],  **ppsd_kwargs)
-        ppsdE.add(eStream)
-
-        #Get ppsds of n component
-        nStream = stream.select(component='N')
-        nstats = nStream.traces[0].stats
-        ppsdN = PPSD(nstats, paz['N'], **ppsd_kwargs)
-        ppsdN.add(nStream)
-
-        #Get ppsds of z component
-        zStream = stream.select(component='Z')
-        zstats = zStream.traces[0].stats
-        ppsdZ = PPSD(zstats, paz['Z'], **ppsd_kwargs)
-        ppsdZ.add(zStream)
-
-        ppsds = {'Z':ppsdZ, 'N':ppsdN, 'E':ppsdE}
-
-        #Add to the input dictionary, so that some items can be manipulated later on, and original can be saved
-        params['ppsds_obspy'] = ppsds
-        params['ppsds'] = {}
-        anyKey = list(params['ppsds_obspy'].keys())[0]
-        
-        #Get ppsd class members
-        members = [mems for mems in dir(params['ppsds_obspy'][anyKey]) if not callable(mems) and not mems.startswith("_")]
-        params['ppsds']['Z'] = {}
-        params['ppsds']['E'] = {}
-        params['ppsds']['N'] = {}
-        
-        #Get lists/arrays so we can manipulate data later and copy everything over to main 'ppsds' subdictionary (convert lists to np.arrays for consistency)
-        listList = ['times_data', 'times_gaps', 'times_processed','current_times_used', 'psd_values'] #Things that need to be converted to np.array first, for consistency
-        timeKeys= ['times_processed','current_times_used','psd_values']
-        timeDiffWarn = True
-        dfList = []
-        time_data = {}
-        time_dict = {}
-        for m in members:
-            params['ppsds']['Z'][m] = getattr(params['ppsds_obspy']['Z'], m)
-            params['ppsds']['E'][m] = getattr(params['ppsds_obspy']['E'], m)
-            params['ppsds']['N'][m] = getattr(params['ppsds_obspy']['N'], m)
-            if m in listList:
-               
-                params['ppsds']['Z'][m] = np.array(params['ppsds']['Z'][m])
-                params['ppsds']['E'][m] = np.array(params['ppsds']['E'][m])
-                params['ppsds']['N'][m] = np.array(params['ppsds']['N'][m])
-            
-            if str(m)=='times_processed':
-                unique_times = np.unique(np.array([params['ppsds']['Z'][m],
-                                          params['ppsds']['E'][m],
-                                          params['ppsds']['N'][m]]))
-                
-                common_times = []
-                for currTime in unique_times:
-                    if currTime in params['ppsds']['Z'][m]:
-                        if currTime in params['ppsds']['E'][m]:
-                            if currTime in params['ppsds']['N'][m]:
-                                common_times.append(currTime)
-
-                cTimeIndList = []
-                for cTime in common_times:
-                    ZArr = params['ppsds']['Z'][m]
-                    EArr = params['ppsds']['E'][m]
-                    NArr = params['ppsds']['N'][m]
-
-                    cTimeIndList.append([int(np.where(ZArr == cTime)[0][0]),
-                                        int(np.where(EArr == cTime)[0][0]),
-                                        int(np.where(NArr == cTime)[0][0])])
-                    
-            #Make sure number of time windows is the same between PPSDs (this can happen with just a few slightly different number of samples)
-            if m in timeKeys:
-                if str(m) != 'times_processed':
-                    time_data[str(m)] = (params['ppsds']['Z'][m], params['ppsds']['E'][m], params['ppsds']['N'][m])
-
-                #print(m, params['ppsds']['Z'][m])
-
-                tSteps_same = params['ppsds']['Z'][m].shape[0] == params['ppsds']['E'][m].shape[0] == params['ppsds']['N'][m].shape[0]
-
-                if not tSteps_same:
-                    shortestTimeLength = min(params['ppsds']['Z'][m].shape[0], params['ppsds']['E'][m].shape[0], params['ppsds']['N'][m].shape[0])
-
-                    maxPctDiff = 0
-                    for comp in params['ppsds'].keys():
-                        currCompTimeLength = params['ppsds'][comp][m].shape[0]
-                        timeLengthDiff = currCompTimeLength - shortestTimeLength
-                        percentageDiff = timeLengthDiff / currCompTimeLength
-                        if percentageDiff > maxPctDiff:
-                            maxPctDiff = percentageDiff
-
-                    for comp in params['ppsds'].keys():
-                        while params['ppsds'][comp][m].shape[0] > shortestTimeLength:
-                            params['ppsds'][comp][m] = params['ppsds'][comp][m][:-1]
-                    
-                    
-                    if maxPctDiff > 0.05 and timeDiffWarn:
-                        warnings.warn(f"\t  Number of ppsd time windows between different components is significantly different: {round(maxPctDiff*100,2)}% > 5%. Last windows will be trimmed.")
-                    elif verbose  and timeDiffWarn:
-                        print(f"\t  Number of ppsd time windows between different components is different by {round(maxPctDiff*100,2)}%. Last window(s) of components with larger number of ppsd windows will be trimmed.")
-                    timeDiffWarn = False #So we only do this warning once, even though there are multiple arrays that need to be trimmed
-
-        for i, currTStep in enumerate(cTimeIndList):
-            colList = []
-            currTStepList = []
-            colList.append('TimesProcessed_Obspy')
-            currTStepList.append(common_times[i])
-            for tk in time_data.keys():
-                colList.append(str(tk)+'_Z')
-                colList.append(str(tk)+'_E')
-                colList.append(str(tk)+'_N')
-                currTStepList.append(time_data[tk][0][currTStep[0]])#z
-                currTStepList.append(time_data[tk][1][currTStep[1]])#e
-                currTStepList.append(time_data[tk][2][currTStep[2]])#n
-
-            dfList.append(currTStepList)
-            
-        hvsrDF = pd.DataFrame(dfList, columns=colList)
-        hvsrDF['TimesProcessed_ObspyEnd'] = hvsrDF['TimesProcessed_Obspy'] + ppsd_kwargs['ppsd_length']
-        
-        #Add other times (for start times)
-        def convert_to_datetime(obspyUTCDateTime):
-            return obspyUTCDateTime.datetime.replace(tzinfo=datetime.timezone.utc)
-
-        def convert_to_mpl_dates(obspyUTCDateTime):
-            return obspyUTCDateTime.matplotlib_date
-
-        hvsrDF['TimesProcessed'] = hvsrDF['TimesProcessed_Obspy'].apply(convert_to_datetime)     
-        hvsrDF['TimesProcessed_End'] = hvsrDF['TimesProcessed'] + datetime.timedelta(days=0,seconds=ppsd_kwargs['ppsd_length']) 
-        hvsrDF['TimesProcessed_MPL'] = hvsrDF['TimesProcessed_Obspy'].apply(convert_to_mpl_dates)
-        hvsrDF['TimesProcessed_MPLEnd'] = hvsrDF['TimesProcessed_MPL'] + (ppsd_kwargs['ppsd_length']/86400)
-        
-        hvsrDF['Use'] = True
-        for gap in params['ppsds']['Z']['times_gaps']:
-            hvsrDF['Use'] = (hvsrDF['TimesProcessed_Obspy'].gt(gap[0]) & hvsrDF['TimesProcessed_Obspy'].gt(gap[1]) )| \
-                                (hvsrDF['TimesProcessed_ObspyEnd'].lt(gap[0]) & hvsrDF['TimesProcessed_ObspyEnd'].lt(gap[1]))# | \
-
-        hvsrDF.set_index('TimesProcessed', inplace=True)
-        params['hvsr_df'] = hvsrDF
-        #Create dict entry to keep track of how many outlier hvsr curves are removed (2-item list with [0]=current number, [1]=original number of curves)
-        params['tsteps_used'] = [hvsrDF['Use'].sum(), hvsrDF['Use'].shape[0]]
-        #params['tsteps_used'] = [params['ppsds']['Z']['times_processed'].shape[0], params['ppsds']['Z']['times_processed'].shape[0]]
-        
-        #Remove outlier ppsds (those derived from data within the windows to be removed)
-
-        if remove_outliers and 'xwindows_out' in params.keys():
-            params = remove_outlier_curves(params, outlier_std=outlier_std, ppsd_length=ppsd_kwargs['ppsd_length'])
-        params['tsteps_used'][0] = params['ppsds']['Z']['current_times_used'].shape[0]
-        
-        params = sprit_utils.make_it_classy(params)
-    
-    params['ProcessingStatus']['PPSDStatus'] = True
-    params = _check_processing_status(params)
-    return params
-
-
-
-def get_char(in_char) -
-
-

Outputs character with proper encoding/decoding

-
- -Expand source code - -
def get_char(in_char):
-    """Outputs character with proper encoding/decoding"""
-    if in_char in greek_chars.keys():
-        out_char = greek_chars[in_char].encode(encoding='utf-8')
-    else:
-        out_char = in_char.encode(encoding='utf-8')
-    return out_char.decode('utf-8')
-
-
-
-def get_metadata(params, write_path='', update_metadata=True, source=None) -
-
-

Get metadata and calculate or get paz parameter needed for PPSD

-

Parameters

-
-
params : dict
-
Dictionary containing all the input and other parameters needed for processing -Ouput from input_params() function
-
write_path : str
-
String with output filepath of where to write updated inventory or metadata file -If not specified, does not write file
-
-

Returns

-
-
params : dict
-
Modified input dictionary with additional key:value pair containing paz dictionary (key = "paz")
-
-
- -Expand source code - -
def get_metadata(params, write_path='', update_metadata=True, source=None):
-    """Get metadata and calculate or get paz parameter needed for PPSD
-
-    Parameters
-    ----------
-    params : dict
-        Dictionary containing all the input and other parameters needed for processing
-            Ouput from input_params() function
-    write_path : str
-        String with output filepath of where to write updated inventory or metadata file
-            If not specified, does not write file 
-
-    Returns
-    -------
-    params : dict
-        Modified input dictionary with additional key:value pair containing paz dictionary (key = "paz")
-    """
-    
-    invPath = params['metapath']
-    raspShakeInstNameList = ['raspberry shake', 'shake', 'raspberry', 'rs', 'rs3d', 'rasp. shake', 'raspshake']
-    if params['instrument'].lower() in raspShakeInstNameList:
-        if update_metadata:
-            params = _update_shake_metadata(filepath=invPath, params=params, write_path=write_path)
-        params = _read_RS_Metadata(params, source=source)
-    else:
-        warnings.warn('{} not currently supported\n Returning input params dictionary.'.format(params['instrument']))
-        return params
-    return params
-
-
-
-def get_report(hvsr_results, report_format='print', plot_type='HVSR p ann C+ p ann Spec', export_path=None, return_results=False, csv_overwrite_opt='append', no_output=False, verbose=False) -
-
-

Print a report of the HVSR analysis (not currently implemented)

-

Parameters

-
-
hvsr_results : dict
-
Dictionary containing all the information about the processed hvsr data
-
report_format : {'csv', 'print', plot}
-
Format in which to print or export the report.
-
plot_type : str, default = 'HVSR p ann C+ p ann Spec
-
What type of plot to plot, if 'plot' part of report_format input
-
export_path : None, bool, or filepath, default = None
-
If None or False, does not export; if True, will export to same directory as the datapath parameter in the input_params() function. -Otherwise, it should be a string or path object indicating where to export results. May be a file or directory. -If a directory is specified, the filename will be -"-". The suffix defaults to png for report_format="plot", csv for 'csv', and does not export if 'print.'
-
return_results : bool, default=False
-
Whether to return results. The following report_formats return the following items: -'plot'- str -'print' - matplotlib.Figure object -'csv' - pandas.DataFrame object -list/tuple - a list or tuple of the above objects, in the same order they are in the report_format list
-
csv_overwrite_opts : str, {'append', 'overwrite', 'keep/rename'}
-
How to handle csv report outputs if the designated csv output file already exists. By default, appends the new information to the end of the existing file.
-
no_output : bool, default=False
-
If True, only reads output to appropriate attribute of data class (ie, print does not print, only reads text into variable). If False, performs as normal.
-
verbose : bool, default=True
-
Whether to print the results to terminal. This is the same output as report_format='print', and will not repeat if that is already selected
-
-

Returns

-
-
If return_results=True, the following report_formats return the following items:
-
'plot'- -matplotlib.Figure object -'print' - str -'csv' - pandas.DataFrame object -list/tuple - a list or tuple of the above objects, in the same order they are in the report_format list
-
-
- -Expand source code - -
def get_report(hvsr_results, report_format='print', plot_type='HVSR p ann C+ p ann Spec', export_path=None, return_results=False, csv_overwrite_opt='append', no_output=False, verbose=False):    
-    """Print a report of the HVSR analysis (not currently implemented)
-        
-    Parameters
-    ----------
-    hvsr_results : dict
-        Dictionary containing all the information about the processed hvsr data
-    report_format : {'csv', 'print', plot}
-        Format in which to print or export the report.
-    plot_type : str, default = 'HVSR p ann C+ p ann Spec
-        What type of plot to plot, if 'plot' part of report_format input
-    export_path : None, bool, or filepath, default = None
-        If None or False, does not export; if True, will export to same directory as the datapath parameter in the input_params() function.
-        Otherwise, it should be a string or path object indicating where to export results. May be a file or directory.
-        If a directory is specified, the filename will be  "<site_name>_<acq_date>_<UTC start time>-<UTC end time>". The suffix defaults to png for report_format="plot", csv for 'csv', and does not export if 'print.'
-    return_results : bool, default=False
-        Whether to return results. The following report_formats return the following items:
-            'plot'- str
-            'print' - matplotlib.Figure object
-            'csv' - pandas.DataFrame object
-            list/tuple - a list or tuple of the above objects, in the same order they are in the report_format list
-    csv_overwrite_opts : str, {'append', 'overwrite', 'keep/rename'}
-        How to handle csv report outputs if the designated csv output file already exists. By default, appends the new information to the end of the existing file.
-    no_output : bool, default=False
-        If True, only reads output to appropriate attribute of data class (ie, print does not print, only reads text into variable). If False, performs as normal.
-    verbose : bool, default=True
-        Whether to print the results to terminal. This is the same output as report_format='print', and will not repeat if that is already selected
-
-    Returns
-    -------
-    If return_results=True, the following report_formats return the following items:
-        'plot'-  matplotlib.Figure object
-        'print' - str
-        'csv' - pandas.DataFrame object
-        list/tuple - a list or tuple of the above objects, in the same order they are in the report_format list
-
-    """
-    #print statement
-    #Check if results are good
-    #Curve pass?
-    orig_args = locals().copy() #Get the initial arguments
-
-    if (verbose and isinstance(hvsr_results, HVSRBatch)) or (verbose and not hvsr_results['batch']):
-        if isinstance(hvsr_results, HVSRData) and hvsr_results['batch']:
-            pass
-        else:
-            print('\nGetting HVSR Report: get_report()')
-            print('\tUsing the following parameters:')
-            for key, value in orig_args.items():
-                if key=='params':
-                    pass
-                else:
-                    print('\t  {}={}'.format(key, value))
-            print()
-
-    if isinstance(hvsr_results, HVSRBatch):
-        if verbose:
-            print('\nGetting Reports: Running in batch mode')
-
-            print('\tUsing parameters:')
-            for key, value in orig_args.items():
-                print(f'\t  {key}={value}')    
-            print()
-        #If running batch, we'll loop through each site
-        for site_name in hvsr_results.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            individual_params = hvsr_results[site_name] #Get what would normally be the "params" variable for each site
-            args['hvsr_results'] = individual_params #reset the params parameter we originally read in to an individual site params
-            if hvsr_results[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                    hvsr_results[site_name] = _get_report_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    hvsr_results[site_name] = hvsr_results[site_name]
-            else:
-                hvsr_results[site_name] = hvsr_results[site_name]
-        
-        combined_csvReport = pd.DataFrame()
-        for site_name in hvsr_results.keys():
-            if 'CSV_Report' in hvsr_results[site_name].keys():
-                combined_csvReport = pd.concat([combined_csvReport, hvsr_results[site_name]['CSV_Report']], ignore_index=True, join='inner')
-        
-        if export_path is not None:
-            if export_path is True:
-                if pathlib.Path(hvsr_results['input_params']['datapath']) in sampleFileKeyMap.values():
-                    csvExportPath = pathlib.Path(os.getcwd())
-                else:
-                    csvExportPath = pathlib.Path(hvsr_results['input_params']['datapath'])
-            elif pathlib.Path(export_path).is_dir():
-                csvExportPath = export_path
-            elif pathlib.Path(export_path).is_file():
-                csvExportPath = export_path.parent
-            else:
-                csvExportPath = pathlib.Path(hvsr_results[site_name].datapath)
-                if csvExportPath.is_dir():
-                    pass
-                else:
-                    csvExportPath = csvExportPath.parent
-                
-            combined_csvReport.to_csv(csvExportPath, index=False)
-        
-        if return_results:
-            return hvsr_results
-    else:
-        #if 'BestPeak' in hvsr_results.keys() and 'PassList' in hvsr_results['BestPeak'].keys():
-        try:
-            curvTestsPassed = (hvsr_results['BestPeak']['PassList']['WindowLengthFreq.'] +
-                                hvsr_results['BestPeak']['PassList']['SignificantCycles']+
-                                hvsr_results['BestPeak']['PassList']['LowCurveStDevOverTime'])
-            curvePass = curvTestsPassed > 2
-            
-            #Peak Pass?
-            peakTestsPassed = ( hvsr_results['BestPeak']['PassList']['PeakFreqClarityBelow'] +
-                        hvsr_results['BestPeak']['PassList']['PeakFreqClarityAbove']+
-                        hvsr_results['BestPeak']['PassList']['PeakAmpClarity']+
-                        hvsr_results['BestPeak']['PassList']['FreqStability']+
-                        hvsr_results['BestPeak']['PassList']['PeakStability_FreqStD']+
-                        hvsr_results['BestPeak']['PassList']['PeakStability_AmpStD'])
-            peakPass = peakTestsPassed >= 5
-        except Exception as e:
-            errMsg= 'No BestPeak identified. Check peak_freq_range or hvsr_band or try to remove bad noise windows using remove_noise() or change processing parameters in process_hvsr() or generate_ppsds(). Otherwise, data may not be usable for HVSR.'
-            print(errMsg)
-            print(e)
-            return hvsr_results
-            #raise RuntimeError('No BestPeak identified. Check peak_freq_range or hvsr_band or try to remove bad noise windows using remove_noise() or change processing parameters in process_hvsr() or generate_ppsds(). Otherwise, data may not be usable for HVSR.')
-    
-        if isinstance(report_format, (list, tuple)):
-            pass
-        else:
-            #We will use a loop later even if it's just one report type, so reformat to prepare for for loop
-            allList = [':', 'all']
-            if report_format.lower() in allList:
-                report_format = ['print', 'csv', 'plot']
-            else:
-                report_format = [report_format]   
-
-        def export_report(export_obj, _export_path, _rep_form):
-            if _export_path is None:
-                return
-            else:
-                if _rep_form == 'csv':
-                    ext = '.csv'
-                elif _rep_form =='plot':
-                    ext='.png'
-                else:
-                    ext=''
-                    
-                sitename=hvsr_results['input_params']['site']#.replace('.', '-')
-                fname = f"{sitename}_{hvsr_results['input_params']['acq_date']}_{str(hvsr_results['input_params']['starttime'].time)[:5]}-{str(hvsr_results['input_params']['endtime'].time)[:5]}{ext}"
-                fname = fname.replace(':', '')
-
-                if _export_path==True:
-                    #Check so we don't write in sample directory
-                    if pathlib.Path(hvsr_results['input_params']['datapath']) in sampleFileKeyMap.values():
-                        if pathlib.Path(os.getcwd()) in sampleFileKeyMap.values(): #Just in case current working directory is also sample directory
-                            inFile = pathlib.Path.home() #Use the path to user's home if all else fails
-                        else:
-                            inFile = pathlib.Path(os.getcwd())
-                    else:
-                        inFile = pathlib.Path(hvsr_results['input_params']['datapath'])
-                                 
-                    if inFile.is_dir():
-                        outFile = inFile.joinpath(fname)
-                    else:
-                        outFile = inFile.with_name(fname)
-                else:
-                    if pathlib.Path(_export_path).is_dir():
-                        outFile = pathlib.Path(_export_path).joinpath(fname)
-                    else:
-                        outFile=pathlib.Path(_export_path)
-
-            if _rep_form == 'csv':
-                if outFile.exists():
-                    existFile = pd.read_csv(outFile)
-                    if csv_overwrite_opt.lower() == 'append':
-                        export_obj = pd.concat([existFile, export_obj], ignore_index=True, join='inner')
-                    elif csv_overwrite_opt.lower() == 'overwrite':
-                        pass
-                    else:# csv_overwrite_opt.lower() in ['keep', 'rename']:
-                        fileNameExists = True
-                        i=1
-                        while fileNameExists:
-                            outFile = outFile.with_stem(f"{outFile.stem}_{i}")
-                            i+=1
-                            if not outFile.exists():
-                                fileNameExists = False
-                try:
-                    print(f'\nSaving csv data to: {outFile}')
-                    export_obj.to_csv(outFile, index_label='ID')
-                except:
-                    warnings.warn("Report not exported. \n\tDataframe to be exported as csv has been saved in hvsr_results['BestPeak']['Report']['CSV_Report]", category=RuntimeWarning)
-            elif _rep_form =='plot':
-                if verbose:
-                    print(f'\nSaving plot to: {outFile}')
-                plt.scf = export_obj
-                plt.savefig(outFile)
-            return 
-
-        def report_output(_report_format, _plot_type='HVSR p ann C+ p ann Spec', _return_results=False, _export_path=None, _no_output=False, verbose=False):
-            if _report_format=='print':
-                #Print results
-
-                #Make separators for nicely formatted print output
-                sepLen = 99
-                siteSepSymbol = '='
-                intSepSymbol = u"\u2013"
-                extSepSymbol = u"\u2014"
-                
-                if sepLen % 2 == 0:
-                    remainVal = 1
-                else:
-                    remainVal = 0
-
-                siteWhitespace = 2
-                #Format the separator lines internal to each site
-                internalSeparator = intSepSymbol.center(sepLen-4, intSepSymbol).center(sepLen, ' ')
-
-                extSiteSeparator = "".center(sepLen, extSepSymbol)
-                siteSeparator = f"{hvsr_results['input_params']['site']}".center(sepLen - siteWhitespace, ' ').center(sepLen, siteSepSymbol)
-                endSiteSeparator = "".center(sepLen, siteSepSymbol)
-
-                #Start building list to print
-                report_string_list = []
-                report_string_list.append("") #Blank line to start
-                report_string_list.append(extSiteSeparator)
-                report_string_list.append(siteSeparator)
-                report_string_list.append(extSiteSeparator)
-                #report_string_list.append(internalSeparator)
-                report_string_list.append('')
-                report_string_list.append(f"\tSite Name: {hvsr_results['input_params']['site']}")
-                report_string_list.append(f"\tAcq. Date: {hvsr_results['input_params']['acq_date']}")
-                report_string_list.append(f"\tLocation : {hvsr_results['input_params']['longitude']}, {hvsr_results['input_params']['latitude']}")
-                report_string_list.append(f"\tElevation: {hvsr_results['input_params']['elevation']}")
-                report_string_list.append('')
-                report_string_list.append(internalSeparator)
-                report_string_list.append('')
-                if 'BestPeak' not in hvsr_results.keys():
-                    report_string_list.append('\tNo identifiable BestPeak was present between {} for {}'.format(hvsr_results['input_params']['hvsr_band'], hvsr_results['input_params']['site']))
-                else:
-                    report_string_list.append('\t{0:.3f} Hz Peak Frequency'.format(hvsr_results['BestPeak']['f0']))        
-                    if curvePass and peakPass:
-                        report_string_list.append('\t  {} Curve at {} Hz passed quality checks! ☺ :D'.format(sprit_utils.check_mark(), round(hvsr_results['BestPeak']['f0'],3)))
-                    else:
-                        report_string_list.append('\t  {} Peak at {} Hz did NOT pass quality checks ☹:('.format(sprit_utils.x_mark(), round(hvsr_results['BestPeak']['f0'],3)))            
-                    report_string_list.append('')
-                    report_string_list.append(internalSeparator)
-                    report_string_list.append('')
-
-                    #Print individual results
-                    report_string_list.append('\tCurve Tests: {}/3 passed (3/3 needed)'.format(curvTestsPassed))
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['Lw'][-1]} Length of processing windows: {hvsr_results['BestPeak']['Report']['Lw']}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['Nc'][-1]} Number of significant cycles: {hvsr_results['BestPeak']['Report']['Nc']}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['σ_A(f)'][-1]} Low StDev. of H/V Curve over time: {hvsr_results['BestPeak']['Report']['σ_A(f)']}")
-
-                    report_string_list.append('')
-                    report_string_list.append("\tPeak Tests: {}/6 passed (5/6 needed)".format(peakTestsPassed))
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['A(f-)'][-1]} Clarity Below Peak Frequency: {hvsr_results['BestPeak']['Report']['A(f-)']}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['A(f+)'][-1]} Clarity Above Peak Frequency: {hvsr_results['BestPeak']['Report']['A(f+)']}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['A0'][-1]} Clarity of Peak Amplitude: {hvsr_results['BestPeak']['Report']['A0']}")
-                    if hvsr_results['BestPeak']['PassList']['FreqStability']:
-                        res = sprit_utils.check_mark()
-                    else:
-                        res = sprit_utils.x_mark()
-                    report_string_list.append(f"\t\t {res} Stability of Peak Freq. Over time: {hvsr_results['BestPeak']['Report']['P-'][:5]} and {hvsr_results['BestPeak']['Report']['P+'][:-1]} {res}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['Sf'][-1]} Stability of Peak (Freq. StDev): {hvsr_results['BestPeak']['Report']['Sf']}")
-                    report_string_list.append(f"\t\t {hvsr_results['BestPeak']['Report']['Sa'][-1]} Stability of Peak (Amp. StDev): {hvsr_results['BestPeak']['Report']['Sa']}")
-                report_string_list.append('')
-                report_string_list.append(f"Calculated using {hvsr_results['hvsr_df']['Use'].sum()}/{hvsr_results['hvsr_df']['Use'].count()} time windows".rjust(sepLen-1))
-                report_string_list.append(extSiteSeparator)
-                #report_string_list.append(endSiteSeparator)
-                #report_string_list.append(extSiteSeparator)
-                report_string_list.append('')
-                
-                reportStr=''
-                #Now print it
-                for line in report_string_list:
-                    reportStr = reportStr+'\n'+line
-
-                if not _no_output:
-                    print(reportStr)
-
-                export_report(export_obj=reportStr, _export_path=_export_path, _rep_form=_report_format)
-                hvsr_results['BestPeak']['Report']['Print_Report'] = reportStr
-                hvsr_results['Print_Report'] = reportStr
-
-            elif _report_format=='csv':
-                import pandas as pd
-                pdCols = ['Site Name', 'Acq_Date', 'Longitude', 'Latitide', 'Elevation', 'PeakFrequency', 
-                        'WindowLengthFreq.','SignificantCycles','LowCurveStDevOverTime',
-                        'PeakFreqClarityBelow','PeakFreqClarityAbove','PeakAmpClarity','FreqStability', 'PeakStability_FreqStD','PeakStability_AmpStD', 'PeakPasses']
-                d = hvsr_results
-                criteriaList = []
-                for p in hvsr_results['BestPeak']["PassList"]:
-                    criteriaList.append(hvsr_results['BestPeak']["PassList"][p])
-                criteriaList.append(hvsr_results['BestPeak']["PeakPasses"])
-                dfList = [[d['input_params']['site'], d['input_params']['acq_date'], d['input_params']['longitude'], d['input_params']['latitude'], d['input_params']['elevation'], round(d['BestPeak']['f0'], 3)]]
-                dfList[0].extend(criteriaList)
-                outDF = pd.DataFrame(dfList, columns=pdCols)
-
-                if verbose:
-                    print('\nCSV Report:\n')
-                    maxColWidth = 13
-                    print('  ', end='')
-                    for col in outDF.columns:
-                        if len(str(col)) > maxColWidth:
-                            colStr = str(col)[:maxColWidth-3]+'...'
-                        else:
-                            colStr = str(col)
-                        print(colStr.ljust(maxColWidth), end='  ')
-                    print() #new line
-                    for c in range(len(outDF.columns) * (maxColWidth+2)):
-                        if c % (maxColWidth+2) == 0:
-                            print('|', end='')
-                        else:
-                            print('-', end='')
-                    print('|') #new line
-                    print('  ', end='') #Small indent at start                    
-                    for row in outDF.iterrows():
-                        for col in row[1]:
-                            if len(str(col)) > maxColWidth:
-                                colStr = str(col)[:maxColWidth-3]+'...'
-                            else:
-                                colStr = str(col)
-                            print(colStr.ljust(maxColWidth), end='  ')
-                        print()
-
-                try:
-                    export_report(export_obj=outDF, _export_path=_export_path, _rep_form=_report_format)
-                except:
-                    print("Error in exporting csv report. CSV not exported")
-                hvsr_results['BestPeak']['Report']['CSV_Report'] = outDF
-                hvsr_results['CSV_Report'] = outDF
-                        
-            elif _report_format=='plot':
-                fig_ax = plot_hvsr(hvsr_results, plot_type=_plot_type, show=False, return_fig=True)
-
-                export_report(export_obj=fig_ax[0], _export_path=_export_path, _rep_form=_report_format)
-                hvsr_results['BestPeak']['Report']['HV_Plot']=hvsr_results['HV_Plot']=fig_ax
-
-                print('\nPlot of data report:')
-                plt.show()
-                
-            return hvsr_results
-
-        for i, rep_form in enumerate(report_format):
-            if isinstance(export_path, (list, tuple)):
-                if not isinstance(report_format, (list, tuple)):
-                    warnings.warn('export_path is a list/tuple and report_format is not. This may result in unexpected behavior.')
-                if isinstance(report_format, (list, tuple)) and isinstance(export_path, (list, tuple)) and len(report_format) != len(export_path):
-                    warnings.warn('export_path and report_format are both lists or tuples, but they are not the same length. This may result in unexpected behavior.')
-            
-                exp_path = export_path[i]
-            else:
-                exp_path = export_path
-            hvsr_results = report_output(_report_format=rep_form, _plot_type=plot_type, _return_results=return_results, _export_path=exp_path, _no_output=no_output, verbose=verbose)
-    return hvsr_results
-
-
-
-def gui() -
-
-

Function to open a window with a graphical user interface (gui)

-

No parameters, no returns; just opens the gui window.

-
- -Expand source code - -
def gui():
-    """Function to open a window with a graphical user interface (gui)
-    
-    No parameters, no returns; just opens the gui window.
-    """
-    import pkg_resources
-    #guiPath = pathlib.Path(os.path.realpath(__file__))
-    try:
-        from sprit.sprit_gui import SPRIT_App
-    except:
-        from sprit_gui import SPRIT_App
-    
-    try:
-        import tkinter as tk
-    except:
-        if sys.platform == 'linux':
-            raise ImportError('The SpRIT graphical interface uses tkinter, which ships with python but is not pre-installed on linux machines. Use "apt-get install python-tk" or "apt-get install python3-tk" to install tkinter. You may need to use the sudo command at the start of those commands.')
-
-    def on_gui_closing():
-        plt.close('all')
-        gui_root.quit()
-        gui_root.destroy()
-
-    if sys.platform == 'linux':
-        if not pathlib.Path("/usr/share/doc/python3-tk").exists():
-            warnings.warn('The SpRIT graphical interface uses tkinter, which ships with python but is not pre-installed on linux machines. Use "apt-get install python-tk" or "apt-get install python3-tk" to install tkinter. You may need to use the sudo command at the start of those commands.')
-
-    gui_root = tk.Tk()
-    try:
-        try:
-            icon_path =pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) 
-            gui_root.iconbitmap(icon_path)
-        except:
-            icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon.png'))
-            gui_root.iconphoto(False, tk.PhotoImage(file=icon_path.as_posix()))
-    except Exception as e:
-        print("ICON NOT LOADED, still opening GUI")
-
-    gui_root.resizable(True, True)
-    SPRIT_App(master=gui_root) #Open the app with a tk.Tk root
-
-    gui_root.protocol("WM_DELETE_WINDOW", on_gui_closing)    
-    gui_root.mainloop() #Run the main loop
-
-
-
-def has_required_channels(stream) -
-
-
-
- -Expand source code - -
def has_required_channels(stream):
-    channel_set = set()
-    
-    # Extract the channel codes from the traces in the stream
-    for trace in stream:
-        channel_set.add(trace.stats.channel)
-    
-    # Check if Z, E, and N channels are present
-    return {'Z', 'E', 'N'}.issubset(channel_set)
-
-
-
-def import_data(import_filepath, data_format='pickle') -
-
-

Function to import .hvsr (or other extension) data exported using export_data() function

-

Parameters

-
-
import_filepath : str or path object
-
Filepath of file created using export_data() function. This is usually a pickle file with a .hvsr extension
-
data_format : str, default='pickle'
-
Type of format data is in. Currently, only 'pickle' supported. Eventually, json or other type may be supported, by default 'pickle'.
-
-

Returns

-
-
HVSRData or HVSRBatch object
-
 
-
-
- -Expand source code - -
def import_data(import_filepath, data_format='pickle'):
-    """Function to import .hvsr (or other extension) data exported using export_data() function
-
-    Parameters
-    ----------
-    import_filepath : str or path object
-        Filepath of file created using export_data() function. This is usually a pickle file with a .hvsr extension
-    data_format : str, default='pickle'
-        Type of format data is in. Currently, only 'pickle' supported. Eventually, json or other type may be supported, by default 'pickle'.
-
-    Returns
-    -------
-    HVSRData or HVSRBatch object
-    """
-    if data_format=='pickle':
-        with open(import_filepath, 'rb') as f:
-            dataIN = pickle.load(f)
-    else:
-        dataIN = import_filepath
-    return dataIN
-
-
-
-def input_params(datapath, site='HVSR Site', network='AM', station='RAC84', loc='00', channels=['EHZ', 'EHN', 'EHE'], acq_date='2023-10-11', starttime='00:00:00.00', endtime='23:59:59.999999', tzone='UTC', xcoord=-88.2290526, ycoord=40.1012122, elevation=755, input_crs='EPSG:4326', output_crs='EPSG:4326', elev_unit='feet', depth=0, instrument='Raspberry Shake', metapath='', hvsr_band=[0.4, 40], peak_freq_range=[0.4, 40], verbose=False) -
-
-

Function for designating input parameters for reading in and processing data

-

Parameters

-
-
datapath : str or pathlib.Path object
-
Filepath of data. This can be a directory or file, but will need to match with what is chosen later as the source parameter in fetch_data()
-
site : str, default="HVSR Site"
-
Site name as designated by user for ease of reference. Used for plotting titles, filenames, etc.
-
network : str, default='AM'
-
The network designation of the seismometer. This is necessary for data from Raspberry Shakes. 'AM' is for Amateur network, which fits Raspberry Shakes.
-
station : str, default='RAC84'
-
The station name of the seismometer. This is necessary for data from Raspberry Shakes.
-
loc : str, default='00'
-
Location information of the seismometer.
-
channels : list, default=['EHZ', 'EHN', 'EHE']
-
The three channels used in this analysis, as a list of strings. Preferred that Z component is first, but not necessary
-
acq_date : str, int, date object, or datetime object
-
If string, preferred format is 'YYYY-MM-DD'. -If int, this will be interpreted as the time_int of year of current year (e.g., 33 would be Feb 2 of current year) -If date or datetime object, this will be the date. Make sure to account for time change when converting to UTC (if UTC is the following time_int, use the UTC time_int).
-
starttime : str, time object, or datetime object, default='00:00:00.00'
-
Start time of data stream. This is necessary for Raspberry Shake data in 'raw' form, or for trimming data. Format can be either 'HH:MM:SS.micros' or 'HH:MM' at minimum.
-
endtime : str, time obejct, or datetime object, default='23:59:99.99'
-
End time of data stream. This is necessary for Raspberry Shake data in 'raw' form, or for trimming data. Same format as starttime.
-
tzone : str or int, default = 'UTC'
-
Timezone of input data. If string, 'UTC' will use the time as input directly. Any other string value needs to be a TZ identifier in the IANA database, a wikipedia page of these is available here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. -If int, should be the int value of the UTC offset (e.g., for American Eastern Standard Time: -5). -This is necessary for Raspberry Shake data in 'raw' format.
-
xcoord : float, default=-88.2290526
-
Longitude (or easting, or, generally, X coordinate) of data point, in Coordinate Reference System (CRS) designated by input_crs. Currently only used in csv output, but will likely be used in future for mapping/profile purposes.
-
ycoord : float, default=40.1012122
-
Latitute (or northing, or, generally, X coordinate) of data point, in Coordinate Reference System (CRS) designated by input_crs. Currently only used in csv output, but will likely be used in future for mapping/profile purposes.
-
input_crs : str or other format read by pyproj, default='EPSG:4326'
-
Coordinate reference system of input data, as used by pyproj.CRS.from_user_input()
-
output_crs : str or other format read by pyproj, default='EPSG:4326'
-
Coordinate reference system to which input data will be transformed, as used by pyproj.CRS.from_user_input()
-
elevation : float, default=755
-
Surface elevation of data point. Not currently used (except in csv output), but will likely be used in the future.
-
depth : float, default=0
-
Depth of seismometer. Not currently used, but will likely be used in the future.
-
instrument : str or list {'Raspberry Shake')
-
Instrument from which the data was acquired.
-
metapath : str or pathlib.Path object, default=''
-
Filepath of metadata, in format supported by obspy.read_inventory. If default value of '', will read from resources folder of repository (only supported for Raspberry Shake).
-
hvsr_band : list, default=[0.4, 40]
-
Two-element list containing low and high "corner" frequencies (in Hz) for processing. This can specified again later.
-
peak_freq_range : list or tuple, default=[0.4, 40]
-
Two-element list or tuple containing low and high frequencies (in Hz) that are used to check for HVSR Peaks. This can be a tigher range than hvsr_band, but if larger, it will still only use the hvsr_band range.
-
verbose : bool, default=False
-
Whether to print output and results to terminal
-
-

Returns

-
-
params : HVSRData
-
sprit.HVSRData class containing input parameters, including data file path and metadata path. This will be used as an input to other functions. If batch processing, params will be converted to batch type in fetch_data() step.
-
-
- -Expand source code - -
def input_params(datapath,
-                site='HVSR Site',
-                network='AM', 
-                station='RAC84', 
-                loc='00', 
-                channels=['EHZ', 'EHN', 'EHE'],
-                acq_date=str(datetime.datetime.now().date()),
-                starttime = '00:00:00.00',
-                endtime = '23:59:59.999999',
-                tzone = 'UTC',
-                xcoord = -88.2290526,
-                ycoord =  40.1012122,
-                elevation = 755,
-                input_crs='EPSG:4326',#4269 is NAD83, defautling to WGS
-                output_crs='EPSG:4326',
-                elev_unit = 'feet',
-                depth = 0,
-                instrument = 'Raspberry Shake',
-                metapath = '',
-                hvsr_band = [0.4, 40],
-                peak_freq_range=[0.4, 40],
-                verbose=False
-                ):
-    """Function for designating input parameters for reading in and processing data
-    
-    Parameters
-    ----------
-    datapath : str or pathlib.Path object
-        Filepath of data. This can be a directory or file, but will need to match with what is chosen later as the source parameter in fetch_data()
-    site : str, default="HVSR Site"
-        Site name as designated by user for ease of reference. Used for plotting titles, filenames, etc.
-    network : str, default='AM'
-        The network designation of the seismometer. This is necessary for data from Raspberry Shakes. 'AM' is for Amateur network, which fits Raspberry Shakes.
-    station : str, default='RAC84'
-        The station name of the seismometer. This is necessary for data from Raspberry Shakes.
-    loc : str, default='00'
-        Location information of the seismometer.
-    channels : list, default=['EHZ', 'EHN', 'EHE']
-        The three channels used in this analysis, as a list of strings. Preferred that Z component is first, but not necessary
-    acq_date : str, int, date object, or datetime object
-        If string, preferred format is 'YYYY-MM-DD'. 
-        If int, this will be interpreted as the time_int of year of current year (e.g., 33 would be Feb 2 of current year)
-        If date or datetime object, this will be the date. Make sure to account for time change when converting to UTC (if UTC is the following time_int, use the UTC time_int).
-    starttime : str, time object, or datetime object, default='00:00:00.00'
-        Start time of data stream. This is necessary for Raspberry Shake data in 'raw' form, or for trimming data. Format can be either 'HH:MM:SS.micros' or 'HH:MM' at minimum.
-    endtime : str, time obejct, or datetime object, default='23:59:99.99'
-        End time of data stream. This is necessary for Raspberry Shake data in 'raw' form, or for trimming data. Same format as starttime.
-    tzone : str or int, default = 'UTC'
-        Timezone of input data. If string, 'UTC' will use the time as input directly. Any other string value needs to be a TZ identifier in the IANA database, a wikipedia page of these is available here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
-        If int, should be the int value of the UTC offset (e.g., for American Eastern Standard Time: -5). 
-        This is necessary for Raspberry Shake data in 'raw' format.
-    xcoord : float, default=-88.2290526
-        Longitude (or easting, or, generally, X coordinate) of data point, in Coordinate Reference System (CRS) designated by input_crs. Currently only used in csv output, but will likely be used in future for mapping/profile purposes.
-    ycoord : float, default=40.1012122
-        Latitute (or northing, or, generally, X coordinate) of data point, in Coordinate Reference System (CRS) designated by input_crs. Currently only used in csv output, but will likely be used in future for mapping/profile purposes.
-    input_crs : str or other format read by pyproj, default='EPSG:4326'
-        Coordinate reference system of input data, as used by pyproj.CRS.from_user_input()
-    output_crs : str or other format read by pyproj, default='EPSG:4326'
-        Coordinate reference system to which input data will be transformed, as used by pyproj.CRS.from_user_input()
-    elevation : float, default=755
-        Surface elevation of data point. Not currently used (except in csv output), but will likely be used in the future.
-    depth : float, default=0
-        Depth of seismometer. Not currently used, but will likely be used in the future.
-    instrument : str or list {'Raspberry Shake')
-        Instrument from which the data was acquired. 
-    metapath : str or pathlib.Path object, default=''
-        Filepath of metadata, in format supported by obspy.read_inventory. If default value of '', will read from resources folder of repository (only supported for Raspberry Shake).
-    hvsr_band : list, default=[0.4, 40]
-        Two-element list containing low and high "corner" frequencies (in Hz) for processing. This can specified again later.
-    peak_freq_range : list or tuple, default=[0.4, 40]
-        Two-element list or tuple containing low and high frequencies (in Hz) that are used to check for HVSR Peaks. This can be a tigher range than hvsr_band, but if larger, it will still only use the hvsr_band range.
-    verbose : bool, default=False
-        Whether to print output and results to terminal
-
-    Returns
-    -------
-    params : sprit.HVSRData
-        sprit.HVSRData class containing input parameters, including data file path and metadata path. This will be used as an input to other functions. If batch processing, params will be converted to batch type in fetch_data() step.
-
-    """
-    orig_args = locals().copy() #Get the initial arguments
-
-    #Declare obspy here instead of at top of file for (for example) colab, where obspy first needs to be installed on environment
-    global obspy
-    import obspy
-    if verbose:
-        print('Gathering input parameters (input_params())')
-        for key, value in orig_args.items():
-            print('\t  {}={}'.format(key, value))
-        print()
-
-    #Make Sure metapath is all good
-    if not pathlib.Path(metapath).exists() or metapath=='':
-        if metapath == '':
-            pass
-        else:
-            print('Specified metadata file cannot be read!')
-        repoDir = pathlib.Path(os.path.dirname(__file__))
-        metapath = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/rs3dv5plus_metadata.inv'))
-        #print('Using default metadata file for Raspberry Shake v.7 distributed with package')
-    else:
-        if isinstance(metapath, pathlib.PurePath):
-            metapath = metapath.as_posix()
-        else:
-            metapath = pathlib.Path(metapath).as_posix()
-
-    #Reformat times
-    if type(acq_date) is datetime.datetime:
-        date = str(acq_date.date())
-    elif type(acq_date) is datetime.date:
-        date=str(acq_date)
-    elif type(acq_date) is str:
-        monthStrs = {'jan':1, 'january':1,
-                    'feb':2, 'february':2,
-                    'mar':3, 'march':3,
-                    'apr':4, 'april':4,
-                    'may':5,
-                    'jun':6, 'june':6,
-                    'jul':7, 'july':7,
-                    'aug':8, 'august':8,
-                    'sep':9, 'sept':9, 'september':9,
-                    'oct':10,'october':10, 
-                    'nov':11,'november':11,
-                    'dec':12,'december':12}
-
-        spelledMonth = False
-        for m in monthStrs.keys():
-            acq_date = acq_date.lower()
-            if m in acq_date:
-                spelledMonth = True
-                break
-
-        if spelledMonth is not False:
-            month = monthStrs[m]
-
-        if '/' in acq_date:
-            sep = '/'
-        elif '.' in acq_date:
-            sep='.'
-        elif ' ' in acq_date:
-            sep = ' '
-            acq_date = acq_date.replace(',', '')
-        else:
-            sep = '-'
-
-        acq_date = acq_date.split(sep)
-        if len(acq_date[2]) > 2: #American format
-            date = '{}-{}-{}'.format(acq_date[2], acq_date[0], acq_date[1])
-        else: #international format, one we're going to use
-            date = '{}-{}-{}'.format(acq_date[0], acq_date[1], acq_date[2])     
-
-    elif type(acq_date) is int:
-        year=datetime.datetime.today().year
-        date = str((datetime.datetime(year, 1, 1) + datetime.timedelta(acq_date - 1)).date())
-    
-    if type(starttime) is str:
-        if 'T' in starttime:
-            #date=starttime.split('T')[0]
-            starttime = starttime.split('T')[1]
-        else:
-            pass
-            #starttime = date+'T'+starttime
-    elif type(starttime) is datetime.datetime:
-        #date = str(starttime.date())
-        starttime = str(starttime.time())
-        ###HERE IS NEXT
-    elif type(starttime) is datetime.time():
-        starttime = str(starttime)
-    
-    starttime = date+"T"+starttime
-    starttime = obspy.UTCDateTime(sprit_utils.format_time(starttime, tzone=tzone))
-    
-    if type(endtime) is str:
-        if 'T' in endtime:
-            date=endtime.split('T')[0]
-            endtime = endtime.split('T')[1]
-    elif type(endtime) is datetime.datetime:
-        date = str(endtime.date())
-        endtime = str(endtime.time())
-    elif type(endtime) is datetime.time():
-        endtime = str(endtime)
-
-    endtime = date+"T"+endtime
-    endtime = obspy.UTCDateTime(sprit_utils.format_time(endtime, tzone=tzone))
-
-    acq_date = datetime.date(year=int(date.split('-')[0]), month=int(date.split('-')[1]), day=int(date.split('-')[2]))
-    raspShakeInstNameList = ['raspberry shake', 'shake', 'raspberry', 'rs', 'rs3d', 'rasp. shake', 'raspshake']
-    
-    #Raspberry shake stationxml is in the resources folder, double check we have right path
-    if instrument.lower() in raspShakeInstNameList:
-        if metapath == r'resources/rs3dv7_metadata.inv':
-            metapath = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/rs3dv7_metadata.inv'))
-            #metapath = pathlib.Path(os.path.realpath(__file__)).parent.joinpath('/resources/rs3dv7_metadata.inv')
-
-    if output_crs is None:
-        output_crs='EPSG:4326'
-
-    if input_crs is None:
-        input_crs = 'EPSG:4326'#Default to WGS84
-    else:        
-        input_crs = CRS.from_user_input(input_crs)
-        output_crs = CRS.from_user_input(output_crs)
-
-        coord_transformer = Transformer.from_crs(input_crs, output_crs, always_xy=True)
-        xcoord, ycoord = coord_transformer.transform(xcoord, ycoord)
-
-    #Add key/values to input parameter dictionary
-    inputParamDict = {'site':site, 'net':network,'sta':station, 'loc':loc, 'cha':channels, 'instrument':instrument,
-                    'acq_date':acq_date,'starttime':starttime,'endtime':endtime, 'timezone':'UTC', #Will be in UTC by this point
-                    'longitude':xcoord,'latitude':ycoord,'elevation':elevation,'input_crs':input_crs, 'output_crs':output_crs,
-                    'depth':depth, 'datapath': datapath, 'metapath':metapath, 'hvsr_band':hvsr_band, 'peak_freq_range':peak_freq_range,
-                    'ProcessingStatus':{'InputStatus':True, 'OverallStatus':True}
-                    }
-    
-    params = sprit_utils.make_it_classy(inputParamDict)
-    params['ProcessingStatus']['InputParams'] = True
-    params = _check_processing_status(params)
-    return params
-
-
-
-def make_it_classy(input_data, verbose=False) -
-
-
-
- -Expand source code - -
def make_it_classy(input_data, verbose=False):
-    if isinstance(input_data, (sprit_hvsr.HVSRData, sprit_hvsr.HVSRBatch)):
-        output_class = input_data
-    else:
-        output_class = sprit_hvsr.HVSRData(input_data)
-    if verbose:
-        print('Made it classy | {} --> {}'.format(type(input_data), type(output_class)))
-    return output_class
-
-
-
-def plot_hvsr(hvsr_data, plot_type='HVSR ann p C+ ann p SPEC', use_subplots=True, xtype='freq', fig=None, ax=None, return_fig=False, save_dir=None, save_suffix='', show_legend=False, show=True, close_figs=False, clear_fig=True, **kwargs) -
-
-

Function to plot HVSR data

-

Parameters

-
-
hvsr_data : dict -
-
Dictionary containing output from process_hvsr function
-
plot_type : str='HVSR' or list -
-
The plot_type of plot(s) to plot. If list, will plot all plots listed -'HVSR' : Standard HVSR plot, including standard deviation -- '[HVSR] p' : HVSR plot with BestPeaks shown -- '[HVSR] p' : HVSR plot with best picked peak shown -
-- '[HVSR] p all' : HVSR plot with all picked peaks shown -
-- '[HVSR] p
t' : HVSR plot with peaks from all time steps in background -
-- '[HVSR p* ann] : Annotates plot with peaks -- '[HVSR] -s' : HVSR plots don't show standard deviation -- '[HVSR] t' : HVSR plot with individual hv curves for each time step shown -- '[HVSR] c' : HVSR plot with each components' spectra. Recommended to do this last (or just before 'specgram'), since doing c+ can make the component chart its own chart -'Specgram' : Combined spectrogram of all components -- '[spec]' : basic spectrogram plot of H/V curve
-
use_subplots : bool, default = True
-
Whether to output the plots as subplots (True) or as separate plots (False)
-
xtype : str, default = 'freq'
-
String for what to use, between frequency or period -For frequency, the following are accepted (case does not matter): 'f', 'Hz', 'freq', 'frequency' -For period, the following are accepted (case does not matter): 'p', 'T', 's', 'sec', 'second', 'per', 'period'
-
fig : matplotlib.Figure, default = None
-
If not None, matplotlib figure on which plot is plotted
-
ax : matplotlib.Axis, default = None
-
If not None, matplotlib axis on which plot is plotted
-
return_fig : bool
-
Whether to return figure and axis objects
-
save_dir : str or None
-
Directory in which to save figures
-
save_suffix : str
-
Suffix to add to end of figure filename(s), if save_dir is used
-
show_legend : bool, default=False
-
Whether to show legend in plot
-
show : bool
-
Whether to show plot
-
close_figs : bool, default=False
-
Whether to close figures before plotting
-
clear_fig : bool, default=True
-
Whether to clear figures before plotting
-
**kwargs : keyword arguments
-
Keyword arguments for matplotlib.pyplot
-
-

Returns

-
-
fig, ax : matplotlib figure and axis objects
-
Returns figure and axis matplotlib.pyplot objects if return_fig=True, otherwise, simply plots the figures
-
-
- -Expand source code - -
def plot_hvsr(hvsr_data, plot_type='HVSR ann p C+ ann p SPEC', use_subplots=True, xtype='freq', fig=None, ax=None, return_fig=False,  save_dir=None, save_suffix='', show_legend=False, show=True, close_figs=False, clear_fig=True,**kwargs):
-    """Function to plot HVSR data
-
-    Parameters
-    ----------
-    hvsr_data : dict                  
-        Dictionary containing output from process_hvsr function
-    plot_type : str='HVSR' or list    
-        The plot_type of plot(s) to plot. If list, will plot all plots listed
-        'HVSR' : Standard HVSR plot, including standard deviation
-        - '[HVSR] p' : HVSR plot with BestPeaks shown
-        - '[HVSR] p' : HVSR plot with best picked peak shown                
-        - '[HVSR] p* all' : HVSR plot with all picked peaks shown                
-        - '[HVSR] p* t' : HVSR plot with peaks from all time steps in background                
-        - '[HVSR p* ann] : Annotates plot with peaks
-        - '[HVSR] -s' : HVSR plots don't show standard deviation
-        - '[HVSR] t' : HVSR plot with individual hv curves for each time step shown
-        - '[HVSR] c' : HVSR plot with each components' spectra. Recommended to do this last (or just before 'specgram'), since doing c+ can make the component chart its own chart
-        'Specgram' : Combined spectrogram of all components
-        - '[spec]' : basic spectrogram plot of H/V curve
-    use_subplots : bool, default = True
-        Whether to output the plots as subplots (True) or as separate plots (False)
-    xtype : str, default = 'freq'    
-        String for what to use, between frequency or period
-            For frequency, the following are accepted (case does not matter): 'f', 'Hz', 'freq', 'frequency'
-            For period, the following are accepted (case does not matter): 'p', 'T', 's', 'sec', 'second', 'per', 'period'
-    fig : matplotlib.Figure, default = None
-        If not None, matplotlib figure on which plot is plotted
-    ax : matplotlib.Axis, default = None
-        If not None, matplotlib axis on which plot is plotted
-    return_fig : bool
-        Whether to return figure and axis objects
-    save_dir : str or None
-        Directory in which to save figures
-    save_suffix : str
-        Suffix to add to end of figure filename(s), if save_dir is used
-    show_legend : bool, default=False
-        Whether to show legend in plot
-    show : bool
-        Whether to show plot
-    close_figs : bool, default=False
-        Whether to close figures before plotting
-    clear_fig : bool, default=True
-        Whether to clear figures before plotting
-    **kwargs : keyword arguments
-        Keyword arguments for matplotlib.pyplot
-
-    Returns
-    -------
-    fig, ax : matplotlib figure and axis objects
-        Returns figure and axis matplotlib.pyplot objects if return_fig=True, otherwise, simply plots the figures
-    """
-    orig_args = locals().copy() #Get the initial arguments
-    if isinstance(hvsr_data, HVSRBatch):
-        #If running batch, we'll loop through each site
-        for site_name in hvsr_data.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            individual_params = hvsr_data[site_name] #Get what would normally be the "params" variable for each site
-            args['hvsr_results'] = individual_params #reset the params parameter we originally read in to an individual site params
-            if hvsr_data[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                    _hvsr_plot_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    print(f"{site_name} not able to be plotted.")
-    else:
-        if clear_fig and fig is not None and ax is not None: #Intended use for tkinter
-            #Clear everything
-            for key in ax:
-                ax[key].clear()
-            fig.clear()
-        if close_figs:
-            plt.close('all')
-
-        compList = ['c', 'comp', 'component', 'components']
-        specgramList = ['spec', 'specgram', 'spectrogram']
-        hvsrList = ['hvsr', 'hv', 'h']
-
-        hvsrInd = np.nan
-        compInd = np.nan
-        specInd = np.nan
-
-        kList = plot_type.split(' ')
-        for i, k in enumerate(kList):
-            kList[i] = k.lower()
-
-        #Get the plots in the right order, no matter how they were input (and ensure the right options go with the right plot)
-        #HVSR index
-        if len(set(hvsrList).intersection(kList)):
-            for i, hv in enumerate(hvsrList):
-                if hv in kList:
-                    hvsrInd = kList.index(hv)
-                    break
-        #Component index
-        #if len(set(compList).intersection(kList)):
-        for i, c in enumerate(kList):
-            if '+' in c and c[:-1] in compList:
-                compInd = kList.index(c)
-                break
-            
-        #Specgram index
-        if len(set(specgramList).intersection(kList)):
-            for i, sp in enumerate(specgramList):
-                if sp in kList:
-                    specInd = kList.index(sp)
-                    break        
-
-        indList = [hvsrInd, compInd, specInd]
-        indListCopy = indList.copy()
-        plotTypeList = ['hvsr', 'comp', 'spec']
-
-        plotTypeOrder = []
-        plotIndOrder = []
-
-        lastVal = 0
-        while lastVal != 99:
-            firstInd = np.nanargmin(indListCopy)
-            plotTypeOrder.append(plotTypeList[firstInd])
-            plotIndOrder.append(indList[firstInd])
-            lastVal = indListCopy[firstInd]
-            indListCopy[firstInd] = 99 #just a high number
-
-        plotTypeOrder.pop()
-        plotIndOrder[-1]=len(kList)
-
-        for i, p in enumerate(plotTypeOrder):
-            pStartInd = plotIndOrder[i]
-            pEndInd = plotIndOrder[i+1]
-            plotComponents = kList[pStartInd:pEndInd]
-
-            if use_subplots and i==0 and fig is None and ax is None:
-                mosaicPlots = []
-                for pto in plotTypeOrder:
-                    mosaicPlots.append([pto])
-                fig, ax = plt.subplot_mosaic(mosaicPlots, gridspec_kw={'hspace':0.3})
-                axis = ax[p]
-            elif use_subplots:
-                with warnings.catch_warnings():
-                    warnings.simplefilter("ignore") #Often warns about xlim when it is not an issue
-                    ax[p].clear()
-                axis = ax[p]
-            else:
-                fig, axis = plt.subplots()
-                    
-            if p == 'hvsr':
-                _plot_hvsr(hvsr_data, fig=fig, ax=axis, plot_type=plotComponents, xtype='x_freqs', show_legend=show_legend, axes=ax)
-            elif p=='comp':
-                plotComponents[0] = plotComponents[0][:-1]
-                _plot_hvsr(hvsr_data, fig=fig, ax=axis, plot_type=plotComponents, xtype='x_freqs', show_legend=show_legend, axes=ax)
-            elif p=='spec':
-                _plot_specgram_hvsr(hvsr_data, fig=fig, ax=axis, colorbar=False)
-            else:
-                warnings.warn('Plot type {p} not recognized', UserWarning)   
-
-        if show:
-            fig.canvas.draw()
-            
-        if return_fig:
-            return fig, ax
-    return
-
-
-
-def process_hvsr(params, method=3, smooth=True, freq_smooth='konno ohmachi', f_smooth_width=40, resample=True, outlier_curve_std=1.75, verbose=False) -
-
-

Process the input data and get HVSR data

-

This is the main function that uses other (private) functions to do -the bulk of processing of the HVSR data and the data quality checks.

-

Parameters

-
-
params -: HVSRData or HVSRBatch
-
Data object containing all the parameters input and generated by the user (usually, during sprit.input_params(), sprit.fetch_data(), sprit.generate_ppsds() and/or sprit.remove_noise()).
-
method -: int or str, default=3
-
Method to use for combining the horizontal components
-
0) (not used)
-
1) Diffuse field assumption, or 'DFA' (not currently implemented)
-
2) 'Arithmetic Mean': H ≡ (HN + HE)/2
-
3) 'Geometric Mean': H ≡ √HN · HE, recommended by the SESAME project (2004)
-
4) 'Vector Summation': H ≡ √H2 N + H2 E
-
5) 'Quadratic Mean': H ≡ √(H2 N + H2 E )/2
-
6) 'Maximum Horizontal Value': H ≡ max
-
smooth -: bool, default=True
-
bool or int may be used.
-
If True, default to smooth H/V curve to using savgoy filter with window length of 51 (works well with default resample of 1000 pts)
-
If int, the length of the window in the savgoy filter.
-
freq_smooth : str {'konno ohmachi', 'constant', 'proportional'}
-
Which frequency smoothing method to use. By default, uses the 'konno ohmachi' method. -- The Konno & Ohmachi method uses the obspy.signal.konnoohmachismoothing.konno_ohmachi_smoothing() function: https://docs.obspy.org/packages/autogen/obspy.signal.konnoohmachismoothing.konno_ohmachi_smoothing.html -- The constant method uses a window of constant length f_smooth_width -- The proportional method uses a window the percentage length of the frequncy steps/range (f_smooth_width now refers to percentage) -See here for more information: https://www.geopsy.org/documentation/geopsy/hv-processing.html
-
f_smooth_width : int, default = 40
-
-
    -
  • For 'konno ohmachi': passed directly to the bandwidth parameter of the konno_ohmachi_smoothing() function, determines the width of the smoothing peak, with lower values resulting in broader peak. Must be > 0.
  • -
  • For 'constant': the size of a triangular smoothing window in the number of frequency steps
  • -
  • For 'proportional': the size of a triangular smoothing window in percentage of the number of frequency steps (e.g., if 1000 frequency steps/bins and f_smooth_width=40, window would be 400 steps wide)
  • -
-
-
resample -: bool, default = True
-
bool or int.
-
If True, default to resample H/V data to include 1000 frequency values for the rest of the analysis
-
If int, the number of data points to interpolate/resample/smooth the component psd/HV curve data to.
-
outlier_curve_std : float, default = 1.75
-
Standard deviation of mean of each H/V curve to use as cuttoff for whether an H/V curve is considered an 'outlier'
-
verbose : bool, defualt=False
-
Whether to print output to terminal
-
-

Returns

-
hvsr_out    : dict
-    Dictionary containing all the information about the data, including input parameters
-
-
- -Expand source code - -
def process_hvsr(params, method=3, smooth=True, freq_smooth='konno ohmachi', f_smooth_width=40, resample=True, outlier_curve_std=1.75, verbose=False):
-    """Process the input data and get HVSR data
-    
-    This is the main function that uses other (private) functions to do 
-    the bulk of processing of the HVSR data and the data quality checks.
-
-    Parameters
-    ----------
-    params  : HVSRData or HVSRBatch
-        Data object containing all the parameters input and generated by the user (usually, during sprit.input_params(), sprit.fetch_data(), sprit.generate_ppsds() and/or sprit.remove_noise()).
-    method  : int or str, default=3
-        Method to use for combining the horizontal components
-            0) (not used)
-            1) Diffuse field assumption, or 'DFA' (not currently implemented)
-            2) 'Arithmetic Mean': H ≡ (HN + HE)/2
-            3) 'Geometric Mean': H ≡ √HN · HE, recommended by the SESAME project (2004)
-            4) 'Vector Summation': H ≡ √H2 N + H2 E
-            5) 'Quadratic Mean': H ≡ √(H2 N + H2 E )/2
-            6) 'Maximum Horizontal Value': H ≡ max {HN, HE}
-    smooth  : bool, default=True
-        bool or int may be used. 
-            If True, default to smooth H/V curve to using savgoy filter with window length of 51 (works well with default resample of 1000 pts)
-            If int, the length of the window in the savgoy filter.
-    freq_smooth : str {'konno ohmachi', 'constant', 'proportional'}
-        Which frequency smoothing method to use. By default, uses the 'konno ohmachi' method.
-            - The Konno & Ohmachi method uses the obspy.signal.konnoohmachismoothing.konno_ohmachi_smoothing() function: https://docs.obspy.org/packages/autogen/obspy.signal.konnoohmachismoothing.konno_ohmachi_smoothing.html
-            - The constant method uses a window of constant length f_smooth_width
-            - The proportional method uses a window the percentage length of the frequncy steps/range (f_smooth_width now refers to percentage)
-        See here for more information: https://www.geopsy.org/documentation/geopsy/hv-processing.html
-    f_smooth_width : int, default = 40
-        - For 'konno ohmachi': passed directly to the bandwidth parameter of the konno_ohmachi_smoothing() function, determines the width of the smoothing peak, with lower values resulting in broader peak. Must be > 0.
-        - For 'constant': the size of a triangular smoothing window in the number of frequency steps
-        - For 'proportional': the size of a triangular smoothing window in percentage of the number of frequency steps (e.g., if 1000 frequency steps/bins and f_smooth_width=40, window would be 400 steps wide)
-    resample  : bool, default = True
-        bool or int. 
-            If True, default to resample H/V data to include 1000 frequency values for the rest of the analysis
-            If int, the number of data points to interpolate/resample/smooth the component psd/HV curve data to.
-    outlier_curve_std : float, default = 1.75
-        Standard deviation of mean of each H/V curve to use as cuttoff for whether an H/V curve is considered an 'outlier'
-    verbose : bool, defualt=False
-        Whether to print output to terminal
-
-    Returns
-    -------
-        hvsr_out    : dict
-            Dictionary containing all the information about the data, including input parameters
-
-    """
-    orig_args = locals().copy() #Get the initial arguments
-    if (verbose and isinstance(params, HVSRBatch)) or (verbose and not params['batch']):
-        if isinstance(params, HVSRData) and params['batch']:
-            pass
-        else:
-            print('\nCalculating Horizontal/Vertical Ratios at all frequencies/time steps (process_hvsr())')
-            print('\tUsing the following parameters:')
-            for key, value in orig_args.items():
-                if key=='params':
-                    pass
-                else:
-                    print('\t  {}={}'.format(key, value))
-            print()
-
-    #First, divide up for batch or not
-    #Site is in the keys anytime it's not batch
-    if isinstance(params, HVSRBatch):
-        #If running batch, we'll loop through each site
-        hvsr_out = {}
-        for site_name in params.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            args['params'] = params[site_name] #Get what would normally be the "params" variable for each site
-            if params[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                    hvsr_out[site_name] = _process_hvsr_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    hvsr_out = params
-                    hvsr_out[site_name]['ProcessingStatus']['HVStatus']=False
-                    hvsr_out[site_name]['ProcessingStatus']['OverallStatus'] = False                    
-            else:
-                hvsr_out = params
-                hvsr_out[site_name]['ProcessingStatus']['HVStatus']=False
-                hvsr_out[site_name]['ProcessingStatus']['OverallStatus'] = False
-        hvsr_out = HVSRBatch(hvsr_out)
-    else:
-        ppsds = params['ppsds'].copy()#[k]['psd_values']
-        ppsds = sprit_utils.check_xvalues(ppsds)
-
-        methodList = ['<placeholder_0>', 'Diffuse Field Assumption', 'Arithmetic Mean', 'Geometric Mean', 'Vector Summation', 'Quadratic Mean', 'Maximum Horizontal Value']
-        x_freqs = {}
-        x_periods = {}
-
-        psdValsTAvg = {}
-        stDev = {}
-        stDevValsP = {}
-        stDevValsM = {}
-        psdRaw={}
-        currTimesUsed={}
-        hvsrDF = params['hvsr_df']
-
-        for k in ppsds.keys():
-            #input_ppsds = ppsds[k]['psd_values'] #original, not used anymore
-            input_ppsds = np.stack(hvsrDF['psd_values_'+k].values)
-
-            currPPSDs = hvsrDF['psd_values_'+k][hvsrDF['Use']].values
-            used_ppsds = np.stack(currPPSDs)
-            
-
-            #if reasmpling has been selected
-            if resample is True or type(resample) is int:
-                if resample is True:
-                    resample = 1000 #Default smooth value
-
-                xValMin = min(ppsds[k]['period_bin_centers'])
-                xValMax = max(ppsds[k]['period_bin_centers'])
-
-                #Resample period bin values
-                x_periods[k] = np.logspace(np.log10(xValMin), np.log10(xValMax), num=resample)
-
-                if smooth or type(smooth) is int:
-                    if smooth:
-                        smooth = 51 #Default smoothing window
-                    elif smooth % 2==0:
-                        smooth = smooth+1
-
-                #Resample raw ppsd values
-                for i, ppsd_t in enumerate(input_ppsds):
-                    if i==0:
-                        psdRaw[k] = np.interp(x_periods[k], ppsds[k]['period_bin_centers'], ppsd_t)
-                        if smooth is not False:
-                            psdRaw[k] = scipy.signal.savgol_filter(psdRaw[k], smooth, 3)
-                    else:
-                        psdRaw[k] = np.vstack((psdRaw[k], np.interp(x_periods[k], ppsds[k]['period_bin_centers'], ppsd_t)))
-                        if smooth is not False:
-                            psdRaw[k][i] = scipy.signal.savgol_filter(psdRaw[k][i], smooth, 3)
-
-            else:
-                #If no resampling desired
-                x_periods[k] = np.array(ppsds[k]['period_bin_centers'])
-                psdRaw[k] = np.array(input_ppsds)
-
-            hvsrDF['psd_values_'+k] = list(psdRaw[k])
-
-            #Get average psd value across time for each channel (used to calc main H/V curve)
-            psdValsTAvg[k] = np.nanmean(np.array(psdRaw[k]), axis=0)
-            x_freqs[k] = np.divide(np.ones_like(x_periods[k]), x_periods[k]) 
-
-            stDev[k] = np.std(psdRaw[k], axis=0)
-            stDevValsM[k] = np.array(psdValsTAvg[k] - stDev[k])
-            stDevValsP[k] = np.array(psdValsTAvg[k] + stDev[k])
-
-            currTimesUsed[k] = np.array(hvsrDF['TimesProcessed_Obspy'][hvsrDF['Use']].values)
-            #currTimesUsed[k] = ppsds[k]['current_times_used'] #original one
-            
-        #Get string of method type
-        if type(method) is int:
-            methodInt = method
-            method = methodList[method]
-        params['method'] = method
-
-        #This gets the main hvsr curve averaged from all time steps
-        anyK = list(x_freqs.keys())[0]
-        hvsr_curve, _ = __get_hvsr_curve(x=x_freqs[anyK], psd=psdValsTAvg, method=methodInt, hvsr_data=params, verbose=verbose)
-        origPPSD = params['ppsds_obspy'].copy()
-
-        #Add some other variables to our output dictionary
-        hvsr_data = {'input_params':params,
-                    'x_freqs':x_freqs,
-                    'hvsr_curve':hvsr_curve,
-                    'x_period':x_periods,
-                    'psd_raw':psdRaw,
-                    'current_times_used': currTimesUsed,
-                    'psd_values_tavg':psdValsTAvg,
-                    'ppsd_std':stDev,
-                    'ppsd_std_vals_m':stDevValsM,
-                    'ppsd_std_vals_p':stDevValsP,
-                    'method':method,
-                    'ppsds':ppsds,
-                    'ppsds_obspy':origPPSD,
-                    'tsteps_used': params['tsteps_used'].copy(),
-                    'hvsr_df':params['hvsr_df']
-                    }
-        
-        hvsr_out = HVSRData(hvsr_data)
-
-        #This is if manual editing was used (should probably be updated at some point to just use masks)
-        if 'xwindows_out' in params.keys():
-            hvsr_out['xwindows_out'] = params['xwindows_out']
-        else:
-            hvsr_out['xwindows_out'] = []
-
-        #These are in other places in the hvsr_out dict, so are redudant
-        #del dir(hvsr_out['input_params'])['_ppsds_obspy']
-        #del hvsr_out['input_params']['_ppsds']
-        #del hvsr_out['input_params']['tsteps_used']
-
-        freq_smooth_ko = ['konno ohmachi', 'konno-ohmachi', 'konnoohmachi', 'konnohmachi', 'ko', 'k']
-        freq_smooth_constant = ['constant', 'const', 'c']
-        freq_smooth_proport = ['proportional', 'proportion', 'prop', 'p']
-
-        #Frequency Smoothing
-        if freq_smooth is False:
-            if verbose:
-                warnings.warn('No frequency smoothing is being applied. This is not recommended for noisy datasets.')
-        elif freq_smooth is True or freq_smooth.lower() in freq_smooth_ko:
-            from obspy.signal import konnoohmachismoothing
-            for k in hvsr_out['psd_raw']:
-                colName = f'psd_values_{k}'
-
-                ppsd_data = np.stack(hvsr_out['hvsr_df'][colName])
-                ppsd_data = hvsr_out['psd_raw'][k]
-
-                freqs = hvsr_out['x_freqs'][k]
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', category=UserWarning) #Filter out UserWarning for just this method, since it throws up a UserWarning that doesn't really matter about dtypes often
-                    smoothed_ppsd_data = konnoohmachismoothing.konno_ohmachi_smoothing(ppsd_data, freqs, bandwidth=f_smooth_width, normalize=True)
-                hvsr_out['psd_raw'][k] = smoothed_ppsd_data
-                hvsr_out['hvsr_df'][colName] = pd.Series(list(smoothed_ppsd_data), index=hvsr_out['hvsr_df'].index)
-
-        elif freq_smooth.lower() in freq_smooth_constant:
-            hvsr_out = __freq_smooth_window(hvsr_out, f_smooth_width, kind_freq_smooth='constant')
-        elif freq_smooth.lower() in freq_smooth_proport:
-            hvsr_out = __freq_smooth_window(hvsr_out, f_smooth_width, kind_freq_smooth='proportional')
-        else:
-            if verbose:
-                warnings.warn(f'You indicated no frequency smoothing should be applied (freq_smooth = {freq_smooth}). This is not recommended for noisy datasets.')
-
-        #Get hvsr curve from three components at each time step
-        anyK = list(hvsr_out['psd_raw'].keys())[0]
-        if method==1 or method =='dfa' or method =='Diffuse Field Assumption':
-            pass ###UPDATE HERE NEXT???__get_hvsr_curve(x=hvsr_out['x_freqs'][anyK], psd=tStepDict, method=methodInt, hvsr_data=hvsr_out, verbose=verbose)
-        else:
-            hvsr_tSteps = []
-            for tStep in range(len(hvsr_out['psd_raw'][anyK])):
-                tStepDict = {}
-                for k in hvsr_out['psd_raw']:
-                    tStepDict[k] = hvsr_out['psd_raw'][k][tStep]
-                hvsr_tstep, _ = __get_hvsr_curve(x=hvsr_out['x_freqs'][anyK], psd=tStepDict, method=methodInt, hvsr_data=hvsr_out, verbose=verbose)
-                hvsr_tSteps.append(np.float32(hvsr_tstep)) #Add hvsr curve for each time step to larger list of arrays with hvsr_curves
-
-        hvsr_out['hvsr_df']['HV_Curves'] = hvsr_tSteps
-
-        hvsr_out['ind_hvsr_curves'] = np.stack(hvsr_out['hvsr_df']['HV_Curves'][hvsr_out['hvsr_df']['Use']])
-        #hvsr_out['ind_hvsr_curves'] = np.array(hvsr_tSteps)
-
-        #Initialize array based only on the curves we are currently using
-        indHVCurvesArr = np.stack(hvsr_out['hvsr_df']['HV_Curves'][hvsr_out['hvsr_df']['Use']])
-        #indHVCurvesArr = hvsr_out['ind_hvsr_curves']
-
-        if outlier_curve_std:
-            #use the standard deviation of each individual curve to determine if it overlapped
-            stdT = np.nanstd(indHVCurvesArr, axis=1)
-            std_stdT= np.nanstd(stdT)
-            avg_stdT= np.nanmean(stdT)
-            bool_col='Use'
-            eval_col='HV_Curves'
-    
-            testCol = hvsr_out['hvsr_df'].loc[hvsr_out['hvsr_df'][bool_col], eval_col].apply(np.nanstd).gt((avg_stdT + (std_stdT * outlier_curve_std)))
-            low_std_val = avg_stdT - (std_stdT * outlier_curve_std)
-            hi_std_val = avg_stdT + (std_stdT * outlier_curve_std)
-
-            #First, do pandas version of it
-            updateUseCol = hvsr_out['hvsr_df'].loc[hvsr_out['hvsr_df'][bool_col], eval_col].apply(np.nanstd).between(low_std_val, hi_std_val, inclusive='both')
-            hvsr_out['hvsr_df'].loc[hvsr_out['hvsr_df'][bool_col], bool_col] = updateUseCol
-
-            #Find psds to get rid of based on standard deviation of each curve (i.e., how curvy is the curve)
-            psds_to_rid = []
-            for i,t in enumerate(indHVCurvesArr):
-                if stdT[i] < avg_stdT - std_stdT*outlier_curve_std or stdT[i] > avg_stdT + std_stdT*outlier_curve_std:
-                    psds_to_rid.append(i)
-
-            for i, r in enumerate(psds_to_rid):
-                index = int(r-i)
-                indHVCurvesArr = np.delete(indHVCurvesArr, index, axis=0)
-
-                for k in hvsr_out['ppsds']:
-                    hvsr_out['psd_raw'][k] = np.delete(hvsr_out['psd_raw'][k], index, axis=0)         
-                    hvsr_out['current_times_used'][k] = np.delete(hvsr_out['current_times_used'][k], index)
-            hvsr_out['tsteps_used'][0] = hvsr_out['ppsds'][k]['current_times_used'].shape[0]
-
-        hvsr_out['ind_hvsr_stdDev'] = np.nanstd(indHVCurvesArr, axis=0)
-
-        #Get peaks for each time step
-        tStepPeaks = []
-        for tStepHVSR in hvsr_tSteps:
-            tStepPeaks.append(__find_peaks(tStepHVSR))
-        hvsr_out['ind_hvsr_peak_indices'] = tStepPeaks
-        hvsr_out['hvsr_df']['CurvesPeakIndices'] = tStepPeaks
-
-        tStepPFList = []
-        for tPeaks in tStepPeaks:
-            tStepPFs = []
-            for pInd in tPeaks:
-                tStepPFs.append(np.float32(hvsr_out['x_freqs'][anyK][pInd]))
-            tStepPFList.append(tStepPFs)
-        hvsr_out['hvsr_df']['CurvesPeakFreqs'] = tStepPFList
-
-        #Get peaks of main HV curve
-        hvsr_out['hvsr_peak_indices'] = __find_peaks(hvsr_out['hvsr_curve'])
-        
-        #Get frequency values at HV peaks in main curve
-        hvsrPF=[]
-        for p in hvsr_out['hvsr_peak_indices']:
-            hvsrPF.append(hvsr_out['x_freqs'][anyK][p])
-        hvsr_out['hvsr_peak_freqs'] = np.array(hvsrPF)
-
-
-        #Get other HVSR parameters (i.e., standard deviations, etc.)
-        hvsr_out = __gethvsrparams(hvsr_out)
-
-        #Include the original obspy stream in the output
-        hvsr_out['input_stream'] = params['input_stream'] #input_stream
-
-        hvsr_out = sprit_utils.make_it_classy(hvsr_out)
-
-        hvsr_out['ProcessingStatus']['HVStatus'] = True
-    hvsr_out = _check_processing_status(hvsr_out)
-
-    return hvsr_out
-
-
-
-def read_from_RS(dest, src='SHAKENAME@HOSTNAME:/opt/data/archive/YEAR/AM/STATION/', opts='az', username='myshake', password='shakeme', hostname='rs.local', year='2023', sta='RAC84', sleep_time=0.1, verbose=True, save_progress=True, method='scp') -
-
-
-
- -Expand source code - -
def read_from_RS(dest, src='SHAKENAME@HOSTNAME:/opt/data/archive/YEAR/AM/STATION/', opts='az', username='myshake', password='shakeme',hostname='rs.local', year='2023', sta='RAC84',sleep_time=0.1, verbose=True, save_progress=True, method='scp'):
-    src = src.replace('SHAKENAME', username)
-    src = src.replace('SHAKENAME', hostname)
-    src = src.replace('YEAR', year)
-    src = src.replace('STATION', sta)
-
-    if method == 'src':
-        """This does not work from within a virtual environment!!!!"""
-        #import pexpect
-        import sys
-        #from pexpect import popen_spawn
-        import time
-        import wexpect
-
-        scp_command = 'scp -r {} "{}"'.format(src, dest)
-
-        print('Command:', scp_command)
-        child = wexpect.spawn(scp_command, timeout=5)
-
-        child.expect("password:")
-        child.sendline(password)
-
-        child.expect(wexpect.EOF)
-
-        print("Files have been successfully transferred to {}!".format(dest))
-    elif method=='rsync':
-        if verbose:
-            opts = opts + 'v'
-        if save_progress:
-            opts = opts + 'p'   
-
-        #import subprocess
-        #subprocess.run(["rsync", "-"+opts, src, dest])
-        #subprocess.run(["rsync", "-"+opts, src, dest])
-
-        import pty
-        #Test, from https://stackoverflow.com/questions/13041732/ssh-password-through-python-subprocess
-        command = [
-            'rsync',
-            "-"+opts,
-            src,
-            dest
-            #'{0}@{1}'.format(shakename, hostname),
-            #'-o', 'NumberOfPasswordPrompts=1',
-            #'sleep {0}'.format(sleep_time),
-        ]
-
-        # PID = 0 for child, and the PID of the child for the parent    
-        pid, child_fd = pty.fork()
-
-        if not pid: # Child process
-            # Replace child process with our SSH process
-            os.execv(command[0], command)
-
-        while True:
-            output = os.read(child_fd, 1024).strip()
-            lower = output.lower()
-            # Write the password
-            if lower.endswith('password:'):
-                os.write(child_fd, password + '\n')
-                break
-            elif 'are you sure you want to continue connecting' in lower:
-                # Adding key to known_hosts
-                os.write(child_fd, 'yes\n')
-            elif 'company privacy warning' in lower:
-                pass # This is an understood message
-            else:
-                print("SSH Connection Failed",
-                    "Encountered unrecognized message when spawning "
-                    "the SSH tunnel: '{0}'".format(output))
-
-    return dest
-
-
-
-def remove_noise(hvsr_data, remove_method='auto', sat_percent=0.995, noise_percent=0.8, sta=2, lta=30, stalta_thresh=[0.5, 5], warmup_time=0, cooldown_time=0, min_win_size=1, remove_raw_noise=False, verbose=False) -
-
-

Function to remove noisy windows from data, using various methods.

-

Methods include -- Manual window selection (by clicking on a chart with spectrogram and stream data), -- Auto window selection, which does the following two in sequence (these can also be done indepently): -- A sta/lta "antitrigger" method (using stalta values to automatically remove triggered windows where there appears to be too much noise) -- A noise threshold method, that cuts off all times where the noise threshold equals more than (by default) 80% of the highest amplitude noise sample for the length specified by lta (in seconds) -- A saturation threshold method, that cuts off all times where the noise threshold equals more than (by default) 99.5% of the highest amplitude noise sample.

-

Parameters

-
-
hvsr_data : dict, obspy.Stream, or obspy.Trace
-
Dictionary containing all the data and parameters for the HVSR analysis
-
remove_method : str, {'auto', 'manual', 'stalta'/'antitrigger', 'saturation threshold', 'noise threshold', 'warmup'/'cooldown'/'buffer'/'warm_cool'}
-
The different methods for removing noise from the dataset. A list of strings will also work, in which case, it should be a list of the above strings. See descriptions above for what how each method works. By default 'auto.' -If remove_method='auto', this is the equivalent of remove_method=['noise threshold', 'antitrigger', 'saturation threshold', 'warm_cool']
-
sat_percent : float, default=0.995
-
Percentage (between 0 and 1), to use as the threshold at which to remove data. This is used in the saturation method. By default 0.995. -If a value is passed that is greater than 1, it will be divided by 100 to obtain the percentage.
-
noise_percent : float, default = 0.8
-
Percentage (between 0 and 1), to use as the threshold at which to remove data, if it persists for longer than time (in seconds (specified by min_win_size)). This is used in the noise threshold method. By default 0.8. -If a value is passed that is greater than 1, it will be divided by 100 to obtain the percentage.
-
sta : int, optional
-
Short term average (STA) window (in seconds), by default 2. For use with sta/lta antitrigger method.
-
lta : int, optional
-
Long term average (STA) window (in seconds), by default 30. For use with sta/lta antitrigger method.
-
stalta_thresh : list, default=[0.5,5]
-
Two-item list or tuple with the thresholds for the stalta antitrigger. The first value (index [0]) is the lower threshold, the second value (index [1] is the upper threshold), by default [0.5,5]
-
warmup_time : int, default=0
-
Time in seconds to allow for warmup of the instrument (or while operator is still near instrument). This will renove any data before this time, by default 0.
-
cooldown_time : int, default=0
-
Time in seconds to allow for cooldown of the instrument (or for when operator is nearing instrument). This will renove any data before this time, by default 0.
-
min_win_size : float, default=1
-
The minumum size a window must be over specified threshold (in seconds) for it to be removed
-
remove_raw_noise : bool, default=False
-
If remove_raw_noise=True, will perform operation on raw data ('input_stream'), rather than potentially already-modified data ('stream').
-
verbose : bool, default=False
-
Whether to print status of remove_noise
-
-

Returns

-
-
output : dict
-
Dictionary similar to hvsr_data, but containing modified data with 'noise' removed
-
-
- -Expand source code - -
def remove_noise(hvsr_data, remove_method='auto', sat_percent=0.995, noise_percent=0.80, sta=2, lta=30, stalta_thresh=[0.5,5], warmup_time=0, cooldown_time=0, min_win_size=1, remove_raw_noise=False, verbose=False):
-    """Function to remove noisy windows from data, using various methods.
-    
-    Methods include 
-    - Manual window selection (by clicking on a chart with spectrogram and stream data), 
-    - Auto window selection, which does the following two in sequence (these can also be done indepently):
-        - A sta/lta "antitrigger" method (using stalta values to automatically remove triggered windows where there appears to be too much noise)
-        - A noise threshold method, that cuts off all times where the noise threshold equals more than (by default) 80% of the highest amplitude noise sample for the length specified by lta (in seconds)
-        - A saturation threshold method, that cuts off all times where the noise threshold equals more than (by default) 99.5% of the highest amplitude noise sample.
-
-    Parameters
-    ----------
-    hvsr_data : dict, obspy.Stream, or obspy.Trace
-        Dictionary containing all the data and parameters for the HVSR analysis
-    remove_method : str, {'auto', 'manual', 'stalta'/'antitrigger', 'saturation threshold', 'noise threshold', 'warmup'/'cooldown'/'buffer'/'warm_cool'}
-        The different methods for removing noise from the dataset. A list of strings will also work, in which case, it should be a list of the above strings. See descriptions above for what how each method works. By default 'auto.'
-        If remove_method='auto', this is the equivalent of remove_method=['noise threshold', 'antitrigger', 'saturation threshold', 'warm_cool']
-    sat_percent : float, default=0.995
-        Percentage (between 0 and 1), to use as the threshold at which to remove data. This is used in the saturation method. By default 0.995. 
-        If a value is passed that is greater than 1, it will be divided by 100 to obtain the percentage.
-    noise_percent : float, default = 0.8
-        Percentage (between 0 and 1), to use as the threshold at which to remove data, if it persists for longer than time (in seconds (specified by min_win_size)). This is used in the noise threshold method. By default 0.8. 
-        If a value is passed that is greater than 1, it will be divided by 100 to obtain the percentage.
-    sta : int, optional
-        Short term average (STA) window (in seconds), by default 2. For use with sta/lta antitrigger method.
-    lta : int, optional
-        Long term average (STA) window (in seconds), by default 30. For use with sta/lta antitrigger method.
-    stalta_thresh : list, default=[0.5,5]
-        Two-item list or tuple with the thresholds for the stalta antitrigger. The first value (index [0]) is the lower threshold, the second value (index [1] is the upper threshold), by default [0.5,5]
-    warmup_time : int, default=0
-        Time in seconds to allow for warmup of the instrument (or while operator is still near instrument). This will renove any data before this time, by default 0.
-    cooldown_time : int, default=0
-        Time in seconds to allow for cooldown of the instrument (or for when operator is nearing instrument). This will renove any data before this time, by default 0.
-    min_win_size : float, default=1
-        The minumum size a window must be over specified threshold (in seconds) for it to be removed
-    remove_raw_noise : bool, default=False
-        If remove_raw_noise=True, will perform operation on raw data ('input_stream'), rather than potentially already-modified data ('stream').
-    verbose : bool, default=False
-        Whether to print status of remove_noise
-
-    Returns
-    -------
-    output : dict
-        Dictionary similar to hvsr_data, but containing modified data with 'noise' removed
-    """
-    orig_args = locals().copy() #Get the initial arguments
-
-    if (verbose and isinstance(hvsr_data, HVSRBatch)) or (verbose and not hvsr_data['batch']):
-        if isinstance(hvsr_data, HVSRData) and hvsr_data['batch']:
-            pass
-        else:
-            print('\nRemoving noisy data windows (remove_noise())')
-            print('\tUsing the following parameters:')
-            for key, value in orig_args.items():
-                if key=='hvsr_data':
-                    pass
-                else:
-                    print('\t  {}={}'.format(key, value))
-
-    #Setup lists
-    manualList = ['manual', 'man', 'm', 'window', 'windows', 'w']
-    autoList = ['auto', 'automatic', 'all', 'a']
-    antitrigger = ['stalta', 'anti', 'antitrigger', 'trigger', 'at']
-    saturationThresh = ['saturation threshold', 'saturation', 'sat', 's']
-    noiseThresh = ['noise threshold', 'noise', 'threshold', 'n']
-    warmup_cooldown=['warmup', 'cooldown', 'warm', 'cool', 'buffer', 'warmup-cooldown', 'warmup_cooldown', 'wc', 'warm_cool', 'warm-cool']
-
-    #Get Stream from hvsr_data
-    if isinstance(hvsr_data, HVSRBatch):
-        #If running batch, we'll loop through each site
-        hvsr_out = {}
-        for site_name in hvsr_data.keys():
-            args = orig_args.copy() #Make a copy so we don't accidentally overwrite
-            args['hvsr_data'] = hvsr_data[site_name] #Get what would normally be the "hvsr_data" variable for each site
-            if hvsr_data[site_name]['ProcessingStatus']['OverallStatus']:
-                try:
-                   hvsr_out[site_name] = __remove_noise_batch(**args) #Call another function, that lets us run this function again
-                except:
-                    hvsr_out[site_name]['ProcessingStatus']['RemoveNoiseStatus']=False
-                    hvsr_out[site_name]['ProcessingStatus']['OverallStatus']=False
-            else:
-                hvsr_data[site_name]['ProcessingStatus']['RemoveNoiseStatus']=False
-                hvsr_data[site_name]['ProcessingStatus']['OverallStatus']=False
-                hvsr_out = hvsr_data
-                
-        output = HVSRBatch(hvsr_out)
-        return output
-
-    elif isinstance(hvsr_data, (HVSRData, dict)):
-        if remove_raw_noise:
-            inStream = hvsr_data['input_stream'].copy()
-        else:
-            inStream = hvsr_data['stream'].copy()
-        output = hvsr_data#.copy()
-    elif isinstance(hvsr_data, (obspy.core.stream.Stream, obspy.core.trace.Trace)):
-        inStream = hvsr_data.copy()
-        output = inStream.copy()
-    else:
-        RuntimeError(f"Input of type type(hvsr_data)={type(hvsr_data)} cannot be used.")
-    
-    outStream = inStream
-    
-    if isinstance(remove_method, str):
-        if ',' in remove_method:
-            remove_method = remove_method.split(',')
-        else:
-            remove_method = [remove_method]
-    elif isinstance(remove_method, (list, tuple)):
-        pass
-    elif not remove_method:
-        remove_method=[None]
-    else:
-        warnings.warn(f"Input value remove_method={remove_method} must be either string, list of strings, None, or False. No noise removal will be carried out. Please choose one of the following: 'manual', 'auto', 'antitrigger', 'noise threshold', 'warmup_cooldown'.")
-        return output
-        
-    #Reorder list so manual is always first
-    if len(set(remove_method).intersection(manualList)) > 0:
-        manInd = list(set(remove_method).intersection(manualList))[0]
-        remove_method.remove(manInd)
-        remove_method.insert(0, manInd)
-        
-    #Go through each type of removal and remove
-    for rem_kind in remove_method:
-        if not rem_kind:
-            break
-        elif rem_kind.lower() in manualList:
-            if isinstance(output, (HVSRData, dict)):
-                if 'xwindows_out' in output.keys():
-                    pass
-                else:
-                    output = _select_windows(output)
-                window_list = output['xwindows_out']
-            if isinstance(outStream, obspy.core.stream.Stream):
-                if window_list is not None:
-                    output['stream'] = __remove_windows(inStream, window_list, warmup_time)
-                else:
-                    output = _select_windows(output)
-            elif isinstance(output, (HVSRData, dict)):
-                pass
-            else:
-                RuntimeError("Only obspy.core.stream.Stream data type is currently supported for manual noise removal method.")     
-        elif rem_kind.lower() in autoList:
-            outStream = __remove_noise_thresh(outStream, noise_percent=noise_percent, lta=lta, min_win_size=min_win_size)
-            outStream = __remove_anti_stalta(outStream, sta=sta, lta=lta, thresh=stalta_thresh)
-            outStream = __remove_noise_saturate(outStream, sat_percent=sat_percent, min_win_size=min_win_size)
-            outStream = __remove_warmup_cooldown(stream=outStream, warmup_time=warmup_time, cooldown_time=cooldown_time)
-        elif rem_kind.lower() in antitrigger:
-            outStream = __remove_anti_stalta(outStream, sta=sta, lta=lta, thresh=stalta_thresh)
-        elif rem_kind.lower() in saturationThresh:
-            outStream = __remove_noise_saturate(outStream, sat_percent=sat_percent, min_win_size=min_win_size)
-        elif rem_kind.lower() in noiseThresh:
-            outStream = __remove_noise_thresh(outStream, noise_percent=noise_percent, lta=lta, min_win_size=min_win_size)
-        elif rem_kind.lower() in warmup_cooldown:
-            outStream = __remove_warmup_cooldown(stream=outStream, warmup_time=warmup_time, cooldown_time=cooldown_time)
-        else:
-            if len(remove_method)==1:
-                warnings.warn(f"Input value remove_method={remove_method} is not recognized. No noise removal will be carried out. Please choose one of the following: 'manual', 'auto', 'antitrigger', 'noise threshold', 'warmup_cooldown'.")
-                break
-            warnings.warn(f"Input value remove_method={remove_method} is not recognized. Continuing with other noise removal methods.")
-
-    #Add output
-    if isinstance(output, (HVSRData, dict)):
-        output['stream'] = outStream
-        output['input_stream'] = hvsr_data['input_stream']
-        output['ProcessingStatus']['RemoveNoiseStatus'] = True
-        output = _check_processing_status(output)
-
-        if 'hvsr_df' in output.keys():
-            hvsrDF = output['hvsr_df']
-            
-            outStream = output['stream'].split()
-            for i, trace in enumerate(outStream):
-                if i ==0:
-                    trEndTime = trace.stats.endtime
-                    comp_end = trace.stats.component
-                    continue
-                trStartTime = trace.stats.starttime
-                comp_start = trace.stats.component
-                
-                if trEndTime < trStartTime and comp_end==comp_start:
-                    gap = [trEndTime,trStartTime]
-                    output['hvsr_df']['Use'] = (hvsrDF['TimesProcessed_Obspy'].gt(gap[0]) & hvsrDF['TimesProcessed_Obspy'].gt(gap[1]) )| \
-                                    (hvsrDF['TimesProcessed_ObspyEnd'].lt(gap[0]) & hvsrDF['TimesProcessed_ObspyEnd'].lt(gap[1]))# | \
-                
-                trEndTime = trace.stats.endtime
-            
-            outStream.merge()
-            output['stream'] = outStream        
-    elif isinstance(hvsr_data, obspy.core.stream.Stream) or isinstance(hvsr_data, obspy.core.trace.Trace):
-        output = outStream
-    else:
-        warnings.warn(f"Output of type {type(output)} for this function will likely result in errors in other processing steps. Returning hvsr_data data.")
-        return hvsr_data
-
-
-    return output
-
-
-
-def run(datapath, source='file', verbose=False, **kwargs) -
-
-

The sprit.run() is the main function that allows you to do all your HVSR processing in one simple step (sprit.run() is how you would call it in your code, but it may also be called using sprit.sprit_hvsr.run())

-

The datapath parameter of sprit.run() is the only required parameter. This can be either a single file, a list of files (one for each component, for example), a directory (in which case, all obspy-readable files will be added to an HVSRBatch instance), a Rasp. Shake raw data directory, or sample data.

-
The sprit.run() function calls the following functions. This is the recommended order/set of functions to run to process HVSR using SpRIT. See the API documentation for these functions for more information:
-- input_params(): The datapath parameter of input_params() is the only required variable, though others may also need to be called for your data to process correctly.
-- fetch_data(): the source parameter of fetch_data() is the only explicit variable in the sprit.run() function aside from datapath and verbose. Everything else gets delivered to the correct function via the kwargs dictionary
-- remove_noise(): by default, the kind of noise removal is remove_method='auto'. See the remove_noise() documentation for more information. If remove_method is set to anything other than one of the explicit options in remove_noise, noise removal will not be carried out.
-- generate_ppsds(): generates ppsds for each component, which will be combined/used later. Any parameter of obspy.signal.spectral_estimation.PPSD() may also be read into this function.
-- process_hvsr(): this is the main function processing the hvsr curve and statistics. See process_hvsr() documentation for more details. The hvsr_band parameter sets the frequency spectrum over which these calculations occur.
-- check_peaks(): this is the main function that will find and 'score' peaks to get a best peak. The parameter peak_freq_range can be set to limit the frequencies within which peaks are checked and scored.
-- get_report(): this is the main function that will print, plot, and/or save the results of the data. See the get_report() API documentation for more information.
-- export_data(): this function exports the final data output as a pickle file (by default, this pickle object has a .hvsr extension). This can be used to read data back into SpRIT without having to reprocess data.
-
-

Parameters

-
-
datapath : str or filepath object that can be read by obspy
-
Filepath to data to be processed. This may be a file or directory, depending on what kind of data is being processed (this can be specified with the source parameter). -For sample data, The following can be specified as the datapath parameter: -- Any integer 1-6 (inclusive), or the string (e.g., datapath="1" or datapath=1 will work) -- The word "sample" before any integer (e.g., datapath="sample1") -- The word "sample" will default to "sample1" if source='file'. -- If source='batch', datapath should be datapath='sample' or datapath='batch'. In this case, it will read and process all the sample files using the HVSRBatch class. Set verbose=True to see all the information in the sample batch csv file.
-
source : str, optional
-
description, by default 'file'
-
verbose : bool, optional
-
description, by default False
-
**kwargs
-
Keyword arguments for the functions listed above. The keyword arguments are unique, so they will get parsed out and passed into the appropriate function.
-
-

Returns

-
-
hvsr_results : HVSRData or HVSRBatch object
-
If a single file/data point is being processed, a HVSRData object will be returned. Otherwise, it will be a HVSRBatch object. See their documention for more information.
-
-

Raises

-
-
RuntimeError
-
If the input parameter may not be read correctly. This is raised if the input_params() function fails. This raises an error since no other data processing or reading steps will be able to carried out correctly.
-
RuntimeError
-
If the data is not read/fetched correctly using fetch_data(), an error will be raised. This is raised if the fetch_data() function fails. This raises an error since no other data processing steps will be able to carried out correctly.
-
RuntimeError
-
If the data being processed is a single file, an error will be raised if generate_ppsds() does not work correctly. No errors are raised for remove_noise() errors (since that is an optional step) and the process_hvsr() step (since that is the last processing step) .
-
-
- -Expand source code - -
def run(datapath, source='file', verbose=False, **kwargs):
-    """The sprit.run() is the main function that allows you to do all your HVSR processing in one simple step (sprit.run() is how you would call it in your code, but it may also be called using sprit.sprit_hvsr.run())
-    
-    The datapath parameter of sprit.run() is the only required parameter. This can be either a single file, a list of files (one for each component, for example), a directory (in which case, all obspy-readable files will be added to an HVSRBatch instance), a Rasp. Shake raw data directory, or sample data.
-    
-        The sprit.run() function calls the following functions. This is the recommended order/set of functions to run to process HVSR using SpRIT. See the API documentation for these functions for more information:
-        - input_params(): The datapath parameter of input_params() is the only required variable, though others may also need to be called for your data to process correctly.
-        - fetch_data(): the source parameter of fetch_data() is the only explicit variable in the sprit.run() function aside from datapath and verbose. Everything else gets delivered to the correct function via the kwargs dictionary
-        - remove_noise(): by default, the kind of noise removal is remove_method='auto'. See the remove_noise() documentation for more information. If remove_method is set to anything other than one of the explicit options in remove_noise, noise removal will not be carried out.
-        - generate_ppsds(): generates ppsds for each component, which will be combined/used later. Any parameter of obspy.signal.spectral_estimation.PPSD() may also be read into this function.
-        - process_hvsr(): this is the main function processing the hvsr curve and statistics. See process_hvsr() documentation for more details. The hvsr_band parameter sets the frequency spectrum over which these calculations occur.
-        - check_peaks(): this is the main function that will find and 'score' peaks to get a best peak. The parameter peak_freq_range can be set to limit the frequencies within which peaks are checked and scored.
-        - get_report(): this is the main function that will print, plot, and/or save the results of the data. See the get_report() API documentation for more information.
-        - export_data(): this function exports the final data output as a pickle file (by default, this pickle object has a .hvsr extension). This can be used to read data back into SpRIT without having to reprocess data.
-
-    Parameters
-    ----------
-    datapath : str or filepath object that can be read by obspy
-        Filepath to data to be processed. This may be a file or directory, depending on what kind of data is being processed (this can be specified with the source parameter). 
-        For sample data, The following can be specified as the datapath parameter:
-            - Any integer 1-6 (inclusive), or the string (e.g., datapath="1" or datapath=1 will work)
-            - The word "sample" before any integer (e.g., datapath="sample1")
-            - The word "sample" will default to "sample1" if source='file'. 
-            - If source='batch', datapath should be datapath='sample' or datapath='batch'. In this case, it will read and process all the sample files using the HVSRBatch class. Set verbose=True to see all the information in the sample batch csv file.
-    source : str, optional
-        _description_, by default 'file'
-    verbose : bool, optional
-        _description_, by default False
-    **kwargs
-        Keyword arguments for the functions listed above. The keyword arguments are unique, so they will get parsed out and passed into the appropriate function.
-
-    Returns
-    -------
-    hvsr_results : sprit.HVSRData or sprit.HVSRBatch object
-        If a single file/data point is being processed, a HVSRData object will be returned. Otherwise, it will be a HVSRBatch object. See their documention for more information.
-
-    Raises
-    ------
-    RuntimeError
-        If the input parameter may not be read correctly. This is raised if the input_params() function fails. This raises an error since no other data processing or reading steps will be able to carried out correctly.
-    RuntimeError
-        If the data is not read/fetched correctly using fetch_data(), an error will be raised. This is raised if the fetch_data() function fails. This raises an error since no other data processing steps will be able to carried out correctly.
-    RuntimeError
-        If the data being processed is a single file, an error will be raised if generate_ppsds() does not work correctly. No errors are raised for remove_noise() errors (since that is an optional step) and the process_hvsr() step (since that is the last processing step) .
-    """
-    #Get the input parameters
-    input_params_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in input_params.__code__.co_varnames}
-    try:
-        params = input_params(datapath=datapath, verbose=verbose, **input_params_kwargs)
-    except:
-        #Even if batch, this is reading in data for all sites so we want to raise error, not just warn
-        raise RuntimeError('Input parameters not read correctly, see sprit.input_params() function and parameters')
-        #If input_params fails, initialize params as an HVSRDATA
-        params = {'ProcessingStatus':{'InputStatus':False, 'OverallStatus':False}}
-        params.update(input_params_kwargs)
-        params = sprit_utils.make_it_classy(params)
-
-    #Fetch Data
-    try:
-        fetch_data_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in fetch_data.__code__.co_varnames}
-        dataIN = fetch_data(params=params, source=source, verbose=verbose, **fetch_data_kwargs)    
-    except:
-        #Even if batch, this is reading in data for all sites so we want to raise error, not just warn
-        raise RuntimeError('Data not read correctly, see sprit.fetch_data() function and parameters for more details.')
-    
-    #Remove Noise
-    try:
-        remove_noise_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in remove_noise.__code__.co_varnames}
-        data_noiseRemoved = remove_noise(hvsr_data=dataIN, verbose=verbose,**remove_noise_kwargs)   
-    except:
-        data_noiseRemoved = dataIN
-        
-        #Reformat data so HVSRData and HVSRBatch data both work here
-        if isinstance(data_noiseRemoved, HVSRData):
-            data_noiseRemoved = {'place_holder_sitename':data_noiseRemoved}
-            dataIN = {'place_holder_sitename':dataIN}
-            
-        for site_name in data_noiseRemoved.keys():
-            data_noiseRemoved[site_name]['ProcessingStatus']['RemoveNoiseStatus']=False
-            #Since noise removal is not required for data processing, check others first
-            if dataIN[site_name]['ProcessingStatus']['OverallStatus']:
-                data_noiseRemoved[site_name]['ProcessingStatus']['OverallStatus'] = True        
-            else:
-                data_noiseRemoved[site_name]['ProcessingStatus']['OverallStatus'] = False
-
-            #If it wasn't originally HVSRBatch, make it HVSRData object again
-            if not data_noiseRemoved[site_name]['batch']:
-                data_noiseRemoved = data_noiseRemoved[site_name]
-    
-    #Generate PPSDs
-    try:
-        generate_ppsds_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in generate_ppsds.__code__.co_varnames}
-        PPSDkwargs = {k: v for k, v in locals()['kwargs'].items() if k in PPSD.__init__.__code__.co_varnames}
-        generate_ppsds_kwargs.update(PPSDkwargs)
-        ppsd_data = generate_ppsds(params=data_noiseRemoved, verbose=verbose,**generate_ppsds_kwargs)
-    except Exception as e:
-        if source == 'file' or source=='raw':
-            if hasattr(e, 'message'):
-                errMsg = e.message
-            else:
-                errMsg = e
-            raise RuntimeError(f"generate_ppsds() error: {errMsg}")
-
-        #Reformat data so HVSRData and HVSRBatch data both work here
-        ppsd_data = data_noiseRemoved
-        if isinstance(ppsd_data, HVSRData):
-            ppsd_data = {'place_holder_sitename':ppsd_data}
-            
-        for site_name in ppsd_data.keys(): #This should work more or less the same for batch and regular data now
-            ppsd_data[site_name]['ProcessingStatus']['PPSDStatus']=False
-            ppsd_data[site_name]['ProcessingStatus']['OverallStatus'] = False
-    
-            #If it wasn't originally HVSRBatch, make it HVSRData object again
-            if not ppsd_data[site_name]['batch']:
-                ppsd_data = ppsd_data[site_name]
-    
-    #Process HVSR Curves
-    try:
-        process_hvsr_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in process_hvsr.__code__.co_varnames}
-        hvsr_results = process_hvsr(params=ppsd_data, verbose=verbose,**process_hvsr_kwargs)
-    except Exception as e:
-        traceback.print_exception(sys.exc_info()[1])
-        exc_type, exc_obj, tb = sys.exc_info()
-        f = tb.tb_frame
-        lineno = tb.tb_lineno
-        filename = f.f_code.co_filename
-        errLineNo = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
-        error_category = type(e).__name__.title().replace('error', 'Error')
-        error_message = f"{e} ({errLineNo})"
-        print(f"{error_category} ({errLineNo}): {error_message}")
-        print(lineno, filename, f)
-
-        hvsr_results = ppsd_data
-        if isinstance(hvsr_results, HVSRData):
-            hvsr_results = {'place_holder_sitename':hvsr_results}
-            
-        for site_name in hvsr_results.keys(): #This should work more or less the same for batch and regular data now
-        
-            hvsr_results[site_name]['ProcessingStatus']['HVStatus']=False
-            hvsr_results[site_name]['ProcessingStatus']['OverallStatus'] = False
-            
-            #If it wasn't originally HVSRBatch, make it HVSRData object again
-            if not hvsr_results[site_name]['batch']:
-                hvsr_results = hvsr_results[site_name]            
-            
-    #Final post-processing/reporting
-
-    #Check peaks
-    check_peaks_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in check_peaks.__code__.co_varnames}
-    hvsr_results = check_peaks(hvsr_data=hvsr_results, verbose=verbose, **check_peaks_kwargs)
-
-    get_report_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in get_report.__code__.co_varnames}
-    get_report(hvsr_results=hvsr_results, verbose=verbose, **get_report_kwargs)
-
-    if verbose:
-        if 'report_format' in get_report_kwargs.keys():
-            #if report_format is 'print', we would have already printed it in previous step
-            if get_report_kwargs['report_format']=='print' or 'print' in get_report_kwargs['report_format'] or isinstance(hvsr_results, HVSRBatch):
-                #We do not need to print another report if already printed to terminal
-                pass
-            else:
-                #We will just change the report_format kwarg to print, since we already got the originally intended report format above, 
-                #   now need to print for verbose output
-                get_report_kwargs['report_format']='print'
-                get_report(hvsr_results=hvsr_results, **get_report_kwargs)
-                
-            if get_report_kwargs['report_format']=='plot' or 'plot' in get_report_kwargs['report_format']:
-                #We do not need to plot another report if already plotted
-                pass
-            else:
-                hvplot_kwargs = {k: v for k, v in locals()['kwargs'].items() if k in plot_hvsr.__code__.co_varnames}
-                hvsr_results['HV_Plot'] = plot_hvsr(hvsr_results, **hvplot_kwargs)
-        else:
-            pass
-    
-    #Export processed data if export_path(as pickle currently, default .hvsr extension)
-    if 'export_path' in kwargs.keys():
-        if kwargs['export_path'] is None:
-            pass
-        else:
-            if 'ext' in kwargs.keys():
-                ext = kwargs['ext']
-            else:
-                ext = 'hvsr'
-            export_data(hvsr_data=hvsr_results, export_path=kwargs['export_path'], ext=ext, verbose=verbose)        
-
-    return hvsr_results
-
-
-
-def time_it(_t, proc_name='', verbose=True) -
-
-

Computes elapsed time since the last call.

-
- -Expand source code - -
def time_it(_t, proc_name='', verbose=True):
-    """Computes elapsed time since the last call."""
-    t1 = datetime.datetime.now().time()
-    dt = t1 - _t
-    t = _t
-    if dt > 0.05:
-        if verbose:
-            print(f'[ELAPSED TIME] {dt:0.1f} s', flush=True)
-        t = t1
-    return t
-
-
-
-
-
-

Classes

-
-
-class HVSRBatch -(*args, **kwargs) -
-
-

HVSRBatch is the data container used for batch processing. It contains several HVSRData objects (one for each site). These can be accessed using their site name, either square brackets (HVSRBatchVariable["SiteName"]) or the dot (HVSRBatchVariable.SiteName) accessor.

-

The dot accessor may not work if there is a space in the site name.

-

All of the -functions in the sprit.pacakge are designed to perform the bulk of their operations iteratively on the individual HVSRData objects contained in the HVSRBatch object, and do little with the HVSRBatch object itself, besides using it determine which sites are contained within it.

-
- -Expand source code - -
class HVSRBatch:
-    """HVSRBatch is the data container used for batch processing. It contains several HVSRData objects (one for each site). These can be accessed using their site name, either square brackets (HVSRBatchVariable["SiteName"]) or the dot (HVSRBatchVariable.SiteName) accessor.
-    
-    The dot accessor may not work if there is a space in the site name.
-    
-    All of the  functions in the sprit.pacakge are designed to perform the bulk of their operations iteratively on the individual HVSRData objects contained in the HVSRBatch object, and do little with the HVSRBatch object itself, besides using it determine which sites are contained within it.
-    
-    """
-    @check_instance
-    def __init__(self, sites_dict):
-      
-        self._batch_dict = sites_dict
-        self.batch_dict = self._batch_dict
-        self.batch = True
-
-        for sitename, hvsrdata in sites_dict.items():
-            setattr(self, sitename, hvsrdata)
-            self[sitename]['batch']=True
-            
-        self.sites = list(self._batch_dict.keys())
-
-    #METHODS
-    def __to_json(self, filepath):
-        """Not yet implemented, but may allow import/export to json files in the future, rather than just .hvsr pickles
-
-        Parameters
-        ----------
-        filepath : filepath object
-            Location to save HVSRBatch object as json
-        """
-        # open the file with the given filepath
-        with open(filepath, 'w') as f:
-            # dump the JSON string to the file
-            json.dump(self, f, default=lambda o: o.__dict__, sort_keys=True, indent=4)
-
-    def export(self, export_path=True, ext='hvsr'):
-        """Method to export HVSRData objects in HVSRBatch container to indivdual .hvsr pickle files.
-
-        Parameters
-        ----------
-        export_path : filepath, default=True
-            Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-        ext : str, optional
-            The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-        """
-        export_data(hvsr_data=self, export_path=export_path, ext=ext)
-
-    def keys(self):
-        """Method to return the "keys" of the HVSRBatch object. For HVSRBatch objects, these are the site names. Functions similar to dict.keys().
-
-        Returns
-        -------
-        dict_keys
-            A dict_keys object listing the site names of each of the HVSRData objects contained in the HVSRBatch object
-        """
-        return self.batch_dict.keys()
-
-    def items(self):
-        """Method to return both the site names and the HVSRData object as a set of dict_items tuples. Functions similar to dict.items().
-
-        Returns
-        -------
-        _type_
-            _description_
-        """
-        return self.batch_dict.items()
-
-    def copy(self, type='shallow'):
-        """Make a copy of the HVSRBatch object. Uses python copy module.
-        
-        Parameters
-        ----------
-        type : str {'shallow', 'deep'}
-            Based on input, creates either a shallow or deep copy of the HVSRBatch object. Shallow is equivalent of copy.copy(). Input of 'deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-    
-        """
-        if type.lower()=='deep':
-            return HVSRBatch(copy.deepcopy(self._batch_dict))
-        else:
-            return HVSRBatch(copy.copy(self._batch_dict))
-
-    #Method wrapper of sprit.plot_hvsr function
-    def plot(self, **kwargs):
-        """Method to plot data, based on the sprit.plot_hvsr() function. All the same kwargs and default values apply as plot_hvsr(). For return_fig, returns it to the 'Plot_Report' attribute of each HVSRData object
-
-        Returns
-        -------
-        _type_
-            _description_
-        """
-        for sitename in self:
-            if 'return_fig' in kwargs.keys() and kwargs['return_fig']:
-                self[sitename]['Plot_Report'] = plot_hvsr(self[sitename], **kwargs)
-            else:
-                plot_hvsr(self[sitename], **kwargs)
-
-        return self
-    
-    def get_report(self, **kwargs):
-        """Method to get report from processed data, in print, graphical, or tabular format.
-
-        Returns
-        -------
-        Variable
-            May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-        """
-        if 'report_format' in kwargs.keys():
-            if 'csv' == kwargs['report_format']:
-                for sitename in self:
-                    rowList = []
-                    rowList.append(get_report(self[sitename], **kwargs))
-                return pd.concat(rowList, ignore_index=True)
-            elif 'plot' == kwargs['report_format']:
-                plotDict = {}
-                for sitename in self:
-                    if 'return_fig' in kwargs.keys() and kwargs['return_fig']:
-                        plotDict[sitename] = get_report(self[sitename], **kwargs)
-                    else:
-                        get_report(self[sitename], **kwargs)
-                return plotDict
-            
-        #Only report_format left is print, doesn't return anything, so doesn't matter if defalut or not
-        for sitename in self:
-            get_report(self[sitename], **kwargs)
-        return
-
-    def report(self, **kwargs):
-        """Wrapper of get_report()"""
-        return self.get_report(**kwargs)
-
-    def __iter__(self):
-        return iter(self._batch_dict.keys())
-
-    def __setitem__(self, key, value):
-        setattr(self, key, value)
-
-    def __getitem__(self, key):
-        return getattr(self, key)
-
-

Methods

-
-
-def copy(self, type='shallow') -
-
-

Make a copy of the HVSRBatch object. Uses python copy module.

-

Parameters

-
-
type : str {'shallow', 'deep'}
-
Based on input, creates either a shallow or deep copy of the HVSRBatch object. Shallow is equivalent of copy.copy(). Input of 'deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-
-
- -Expand source code - -
def copy(self, type='shallow'):
-    """Make a copy of the HVSRBatch object. Uses python copy module.
-    
-    Parameters
-    ----------
-    type : str {'shallow', 'deep'}
-        Based on input, creates either a shallow or deep copy of the HVSRBatch object. Shallow is equivalent of copy.copy(). Input of 'deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-
-    """
-    if type.lower()=='deep':
-        return HVSRBatch(copy.deepcopy(self._batch_dict))
-    else:
-        return HVSRBatch(copy.copy(self._batch_dict))
-
-
-
-def export(self, export_path=True, ext='hvsr') -
-
-

Method to export HVSRData objects in HVSRBatch container to indivdual .hvsr pickle files.

-

Parameters

-
-
export_path : filepath, default=True
-
Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-
ext : str, optional
-
The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-
-
- -Expand source code - -
def export(self, export_path=True, ext='hvsr'):
-    """Method to export HVSRData objects in HVSRBatch container to indivdual .hvsr pickle files.
-
-    Parameters
-    ----------
-    export_path : filepath, default=True
-        Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-    ext : str, optional
-        The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-    """
-    export_data(hvsr_data=self, export_path=export_path, ext=ext)
-
-
-
-def get_report(self, **kwargs) -
-
-

Method to get report from processed data, in print, graphical, or tabular format.

-

Returns

-
-
Variable
-
May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-
-
- -Expand source code - -
def get_report(self, **kwargs):
-    """Method to get report from processed data, in print, graphical, or tabular format.
-
-    Returns
-    -------
-    Variable
-        May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-    """
-    if 'report_format' in kwargs.keys():
-        if 'csv' == kwargs['report_format']:
-            for sitename in self:
-                rowList = []
-                rowList.append(get_report(self[sitename], **kwargs))
-            return pd.concat(rowList, ignore_index=True)
-        elif 'plot' == kwargs['report_format']:
-            plotDict = {}
-            for sitename in self:
-                if 'return_fig' in kwargs.keys() and kwargs['return_fig']:
-                    plotDict[sitename] = get_report(self[sitename], **kwargs)
-                else:
-                    get_report(self[sitename], **kwargs)
-            return plotDict
-        
-    #Only report_format left is print, doesn't return anything, so doesn't matter if defalut or not
-    for sitename in self:
-        get_report(self[sitename], **kwargs)
-    return
-
-
-
-def items(self) -
-
-

Method to return both the site names and the HVSRData object as a set of dict_items tuples. Functions similar to dict.items().

-

Returns

-
-
_type_
-
description
-
-
- -Expand source code - -
def items(self):
-    """Method to return both the site names and the HVSRData object as a set of dict_items tuples. Functions similar to dict.items().
-
-    Returns
-    -------
-    _type_
-        _description_
-    """
-    return self.batch_dict.items()
-
-
-
-def keys(self) -
-
-

Method to return the "keys" of the HVSRBatch object. For HVSRBatch objects, these are the site names. Functions similar to dict.keys().

-

Returns

-
-
dict_keys
-
A dict_keys object listing the site names of each of the HVSRData objects contained in the HVSRBatch object
-
-
- -Expand source code - -
def keys(self):
-    """Method to return the "keys" of the HVSRBatch object. For HVSRBatch objects, these are the site names. Functions similar to dict.keys().
-
-    Returns
-    -------
-    dict_keys
-        A dict_keys object listing the site names of each of the HVSRData objects contained in the HVSRBatch object
-    """
-    return self.batch_dict.keys()
-
-
-
-def plot(self, **kwargs) -
-
-

Method to plot data, based on the sprit.plot_hvsr() function. All the same kwargs and default values apply as plot_hvsr(). For return_fig, returns it to the 'Plot_Report' attribute of each HVSRData object

-

Returns

-
-
_type_
-
description
-
-
- -Expand source code - -
def plot(self, **kwargs):
-    """Method to plot data, based on the sprit.plot_hvsr() function. All the same kwargs and default values apply as plot_hvsr(). For return_fig, returns it to the 'Plot_Report' attribute of each HVSRData object
-
-    Returns
-    -------
-    _type_
-        _description_
-    """
-    for sitename in self:
-        if 'return_fig' in kwargs.keys() and kwargs['return_fig']:
-            self[sitename]['Plot_Report'] = plot_hvsr(self[sitename], **kwargs)
-        else:
-            plot_hvsr(self[sitename], **kwargs)
-
-    return self
-
-
-
-def report(self, **kwargs) -
-
-

Wrapper of get_report()

-
- -Expand source code - -
def report(self, **kwargs):
-    """Wrapper of get_report()"""
-    return self.get_report(**kwargs)
-
-
-
-
-
-class HVSRData -(*args, **kwargs) -
-
-

HVSRData is the basic data class of the sprit package. It contains all the processed data, input parameters, and reports.

-

These attributes and objects can be accessed using square brackets or the dot accessor. For example, to access the site name, HVSRData['site'] and HVSRData.site will both return the site name.

-

Some of the methods that work on the HVSRData object (e.g., .plot() and .get_report()) are essentially wrappers for some of the main sprit package functions (sprit.plot_hvsr() and sprit.get_report(), respectively)

-
- -Expand source code - -
class HVSRData:
-    """HVSRData is the basic data class of the sprit package. It contains all the processed data, input parameters, and reports.
-    
-    These attributes and objects can be accessed using square brackets or the dot accessor. For example, to access the site name, HVSRData['site'] and HVSRData.site will both return the site name.
-    
-    Some of the methods that work on the HVSRData object (e.g., .plot() and .get_report()) are essentially wrappers for some of the main sprit package functions (sprit.plot_hvsr() and sprit.get_report(), respectively)
-    """
-    #Old way of using this
-    #def __new__(cls, params):
-    #    if isinstance(params, (cls, HVSRBatch)):
-    #        return params
-    #    return super().__new__(cls)
-
-    @check_instance    
-    def __init__(self, params):
-        self.params = params
-        #self.datastream = None
-        self.batch = False
-        #self.tsteps_used = []
-
-        for key, value in params.items():
-            setattr(self, key, value)
-            if key=='input_params':
-                for k, v in params[key].items():
-                    setattr(self, k, v)
-
-    def __setitem__(self, key, value):
-        setattr(self, key, value)
-
-    def __getitem__(self, key):
-        return getattr(self, key)
-
-    def __to_json(self, filepath):
-        """Not yet supported, will export HVSRData object to json"""
-        # open the file with the given filepath
-        def unseriable_fun(o):
-            if isinstance(o, np.ndarray):
-                output = o.tolist()
-            try:
-                output = o.__dict__
-            except:
-                output = dir(o)
-            return output
-
-        with open(filepath, 'w') as f:
-            # dump the JSON string to the file
-            json.dump(self, f, default=unseriable_fun, sort_keys=True, indent=4)
-
-    def export(self, export_path=None, ext='hvsr'):
-        """Method to export HVSRData objects to .hvsr pickle files.
-
-        Parameters
-        ----------
-        export_path : filepath, default=True
-            Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-        ext : str, optional
-            The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-        """
-        export_data(hvsr_data=self, export_path=export_path, ext=ext)
-
-    #METHODS (many reflect dictionary methods)
-    def keys(self):
-        """Method to return the "keys" of the HVSRData object. For HVSRData objects, these are the attributes and parameters of the object. Functions similar to dict.keys().
-
-        Returns
-        -------
-        dict_keys
-            A dict_keys object of the HVSRData objects attributes, parameters, etc.
-        """        
-        keyList = []
-        for k in dir(self):
-            if not k.startswith('_'):
-                keyList.append(k)
-        return keyList
-
-    def items(self):
-        """Method to return the "items" of the HVSRData object. For HVSRData objects, this is a dict_items object with the keys and values in tuples. Functions similar to dict.items().
-
-        Returns
-        -------
-        dict_items
-            A dict_items object of the HVSRData objects attributes, parameters, etc.
-        """                
-        return self.params.items()
-
-    def copy(self, type='shallow'):
-        """Make a copy of the HVSRData object. Uses python copy module.
-        
-        Parameters
-        ----------
-        type : str {'shallow', 'deep'}
-            Based on input, creates either a shallow or deep copy of the HVSRData object. Shallow is equivalent of copy.copy(). Input of type='deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-    
-        """
-        if type.lower()=='deep':
-            return HVSRData(copy.deepcopy(self.params))
-        else:
-            return HVSRData(copy.copy(self.params))
-        
-    def plot(self, **kwargs):
-        """Method to plot data, wrapper of sprit.plot_hvsr()
-
-        Returns
-        -------
-        matplotlib.Figure, matplotlib.Axis (if return_fig=True)
-        """
-        if 'close_figs' not in kwargs.keys():
-            kwargs['close_figs']=True
-        plot_return = plot_hvsr(self, **kwargs)
-        plt.show()
-        return plot_return
-        
-    def get_report(self, **kwargs):
-        """Method to get report from processed data, in print, graphical, or tabular format.
-
-        Returns
-        -------
-        Variable
-            May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-        """
-        report_return = get_report(self, **kwargs)
-        return report_return
-
-    def report(self, **kwargs):
-        """Wrapper of get_report()"""
-        report_return = get_report(self, **kwargs)
-        return report_return
-    
-    #ATTRIBUTES
-    #params
-    @property
-    def params(self):
-        """Dictionary containing the parameters used to process the data
-
-        Returns
-        -------
-        dict
-            Dictionary containing the process parameters
-        """
-        return self._params
-
-    @params.setter
-    def params(self, value):
-        if not (isinstance(value, dict)):
-            raise ValueError("params must be a dict type, currently passing {} type.".format(type(value)))
-        self._params = value
-    
-    #datastream
-    @property
-    def datastream(self):
-        """A copy of the original obspy datastream read in. This helps to retain the original data even after processing is carried out.
-
-        Returns
-        -------
-        obspy.core.Stream.stream
-            Obspy stream
-        """
-        return self._datastream
-
-    @datastream.setter
-    def datastream(self, value):
-        if value is not None and (not isinstance(value, obspy.core.stream.Stream)):
-            raise ValueError("datastream must be an obspy Stream.")
-        self._datastream = value
-        
-    #batch
-    @property
-    def batch(self):
-        """Whether this HVSRData object is part of an HVSRBatch object. This is used throughout the code to help direct the object into the proper processing pipeline.
-
-        Returns
-        -------
-        bool
-            True if HVSRData object is part of HVSRBatch object, otherwise, False
-        """
-        return self._batch
-
-    @batch.setter
-    def batch(self, value):
-        if value == 0:
-            value = False
-        elif value == 1:
-            value = True
-        else:
-            value = None
-        if not isinstance(value, bool):
-            raise ValueError("batch must be boolean type")
-        self._batch = value
-
-    #PPSD object from obspy (static)
-    @property
-    def ppsds_obspy(self):
-        """The original ppsd information from the obspy.signal.spectral_estimation.PPSD(), so as to keep original if copy is manipulated/changed."""        
-        return self._ppsds_obspy
-
-    @ppsds_obspy.setter
-    def ppsds_obspy(self, value):
-        """Checks whether the ppsd_obspy is of the proper type before saving as attribute"""
-        if not isinstance(value, obspy.signal.spectral_estimation.PPSD):
-            if not isinstance(value, dict):
-                raise ValueError("ppsds_obspy must be obspy.PPSD or dict with osbpy.PPSDs")
-            else:
-                for key in value.keys():
-                    if not isinstance(value[key], obspy.signal.spectral_estimation.PPSD):
-                        raise ValueError("ppsds_obspy must be obspy.PPSD or dict with osbpy.PPSDs")
-        self._ppsds_obspy=value
-                        
-    #PPSD dict, copied from obspy ppsds (dynamic)
-    @property
-    def ppsds(self):
-        """Dictionary copy of the class object obspy.signal.spectral_estimation.PPSD(). The dictionary copy allows manipulation of the data in PPSD, whereas that data cannot be easily manipulated in the original Obspy object.
-
-        Returns
-        -------
-        dict
-            Dictionary copy of the PPSD information from generate_ppsds()
-        """
-        return self._ppsds
-
-    @ppsds.setter
-    def ppsds(self, value):
-        if not isinstance(value, dict):
-            raise ValueError("ppsds dict with infomration from osbpy.PPSD (created by sprit.generate_ppsds())")                  
-        self._ppsds=value
-
-

Instance variables

-
-
var batch
-
-

Whether this HVSRData object is part of an HVSRBatch object. This is used throughout the code to help direct the object into the proper processing pipeline.

-

Returns

-
-
bool
-
True if HVSRData object is part of HVSRBatch object, otherwise, False
-
-
- -Expand source code - -
@property
-def batch(self):
-    """Whether this HVSRData object is part of an HVSRBatch object. This is used throughout the code to help direct the object into the proper processing pipeline.
-
-    Returns
-    -------
-    bool
-        True if HVSRData object is part of HVSRBatch object, otherwise, False
-    """
-    return self._batch
-
-
-
var datastream
-
-

A copy of the original obspy datastream read in. This helps to retain the original data even after processing is carried out.

-

Returns

-
-
obspy.core.Stream.stream
-
Obspy stream
-
-
- -Expand source code - -
@property
-def datastream(self):
-    """A copy of the original obspy datastream read in. This helps to retain the original data even after processing is carried out.
-
-    Returns
-    -------
-    obspy.core.Stream.stream
-        Obspy stream
-    """
-    return self._datastream
-
-
-
var params
-
-

Dictionary containing the parameters used to process the data

-

Returns

-
-
dict
-
Dictionary containing the process parameters
-
-
- -Expand source code - -
@property
-def params(self):
-    """Dictionary containing the parameters used to process the data
-
-    Returns
-    -------
-    dict
-        Dictionary containing the process parameters
-    """
-    return self._params
-
-
-
var ppsds
-
-

Dictionary copy of the class object obspy.signal.spectral_estimation.PPSD(). The dictionary copy allows manipulation of the data in PPSD, whereas that data cannot be easily manipulated in the original Obspy object.

-

Returns

-
-
dict
-
Dictionary copy of the PPSD information from generate_ppsds()
-
-
- -Expand source code - -
@property
-def ppsds(self):
-    """Dictionary copy of the class object obspy.signal.spectral_estimation.PPSD(). The dictionary copy allows manipulation of the data in PPSD, whereas that data cannot be easily manipulated in the original Obspy object.
-
-    Returns
-    -------
-    dict
-        Dictionary copy of the PPSD information from generate_ppsds()
-    """
-    return self._ppsds
-
-
-
var ppsds_obspy
-
-

The original ppsd information from the obspy.signal.spectral_estimation.PPSD(), so as to keep original if copy is manipulated/changed.

-
- -Expand source code - -
@property
-def ppsds_obspy(self):
-    """The original ppsd information from the obspy.signal.spectral_estimation.PPSD(), so as to keep original if copy is manipulated/changed."""        
-    return self._ppsds_obspy
-
-
-
-

Methods

-
-
-def copy(self, type='shallow') -
-
-

Make a copy of the HVSRData object. Uses python copy module.

-

Parameters

-
-
type : str {'shallow', 'deep'}
-
Based on input, creates either a shallow or deep copy of the HVSRData object. Shallow is equivalent of copy.copy(). Input of type='deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-
-
- -Expand source code - -
def copy(self, type='shallow'):
-    """Make a copy of the HVSRData object. Uses python copy module.
-    
-    Parameters
-    ----------
-    type : str {'shallow', 'deep'}
-        Based on input, creates either a shallow or deep copy of the HVSRData object. Shallow is equivalent of copy.copy(). Input of type='deep' is equivalent of copy.deepcopy() (still experimental). Defaults to shallow.
-
-    """
-    if type.lower()=='deep':
-        return HVSRData(copy.deepcopy(self.params))
-    else:
-        return HVSRData(copy.copy(self.params))
-
-
-
-def export(self, export_path=None, ext='hvsr') -
-
-

Method to export HVSRData objects to .hvsr pickle files.

-

Parameters

-
-
export_path : filepath, default=True
-
Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-
ext : str, optional
-
The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-
-
- -Expand source code - -
def export(self, export_path=None, ext='hvsr'):
-    """Method to export HVSRData objects to .hvsr pickle files.
-
-    Parameters
-    ----------
-    export_path : filepath, default=True
-        Filepath to save file. Can be either directory (which will assign a filename based on the HVSRData attributes). By default True. If True, it will first try to save each file to the same directory as datapath, then if that does not work, to the current working directory, then to the user's home directory, by default True
-    ext : str, optional
-        The extension to use for the output, by default 'hvsr'. This is still a pickle file that can be read with pickle.load(), but will have .hvsr extension.
-    """
-    export_data(hvsr_data=self, export_path=export_path, ext=ext)
-
-
-
-def get_report(self, **kwargs) -
-
-

Method to get report from processed data, in print, graphical, or tabular format.

-

Returns

-
-
Variable
-
May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-
-
- -Expand source code - -
def get_report(self, **kwargs):
-    """Method to get report from processed data, in print, graphical, or tabular format.
-
-    Returns
-    -------
-    Variable
-        May return nothing, pandas.Dataframe, or pyplot Figure, depending on input.
-    """
-    report_return = get_report(self, **kwargs)
-    return report_return
-
-
-
-def items(self) -
-
-

Method to return the "items" of the HVSRData object. For HVSRData objects, this is a dict_items object with the keys and values in tuples. Functions similar to dict.items().

-

Returns

-
-
dict_items
-
A dict_items object of the HVSRData objects attributes, parameters, etc.
-
-
- -Expand source code - -
def items(self):
-    """Method to return the "items" of the HVSRData object. For HVSRData objects, this is a dict_items object with the keys and values in tuples. Functions similar to dict.items().
-
-    Returns
-    -------
-    dict_items
-        A dict_items object of the HVSRData objects attributes, parameters, etc.
-    """                
-    return self.params.items()
-
-
-
-def keys(self) -
-
-

Method to return the "keys" of the HVSRData object. For HVSRData objects, these are the attributes and parameters of the object. Functions similar to dict.keys().

-

Returns

-
-
dict_keys
-
A dict_keys object of the HVSRData objects attributes, parameters, etc.
-
-
- -Expand source code - -
def keys(self):
-    """Method to return the "keys" of the HVSRData object. For HVSRData objects, these are the attributes and parameters of the object. Functions similar to dict.keys().
-
-    Returns
-    -------
-    dict_keys
-        A dict_keys object of the HVSRData objects attributes, parameters, etc.
-    """        
-    keyList = []
-    for k in dir(self):
-        if not k.startswith('_'):
-            keyList.append(k)
-    return keyList
-
-
-
-def plot(self, **kwargs) -
-
-

Method to plot data, wrapper of sprit.plot_hvsr()

-

Returns

-
-
matplotlib.Figure, matplotlib.Axis (if return_fig=True)
-
 
-
-
- -Expand source code - -
def plot(self, **kwargs):
-    """Method to plot data, wrapper of sprit.plot_hvsr()
-
-    Returns
-    -------
-    matplotlib.Figure, matplotlib.Axis (if return_fig=True)
-    """
-    if 'close_figs' not in kwargs.keys():
-        kwargs['close_figs']=True
-    plot_return = plot_hvsr(self, **kwargs)
-    plt.show()
-    return plot_return
-
-
-
-def report(self, **kwargs) -
-
-

Wrapper of get_report()

-
- -Expand source code - -
def report(self, **kwargs):
-    """Wrapper of get_report()"""
-    report_return = get_report(self, **kwargs)
-    return report_return
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file diff --git a/docs/sprit_cli.html b/docs/sprit_cli.html index a748986..01d2f3c 100644 --- a/docs/sprit_cli.html +++ b/docs/sprit_cli.html @@ -81,7 +81,6 @@

Module sprit.sprit_cli

parameters = [] for f in hvsrFunctions: parameters.append(inspect.signature(f).parameters) - #Add argument and options to the parser intermediate_params_list = ['params', 'input', 'hvsr_data', 'hvsr_results'] paramNamesList = [] @@ -101,17 +100,20 @@

Module sprit.sprit_cli

# Add more arguments/options as needed args = parser.parse_args() - + # Map command-line arguments/options to kwargs kwargs = {} for arg_name, arg_value in vars(args).items(): if isinstance(arg_value, str): if "=" in arg_value: arg_value = {arg_value.split('=')[0]: arg_value.split('=')[1]} + if arg_value.lower()=='true': arg_value = True elif arg_value.lower()=='false': arg_value = False + elif arg_value.lower() == 'none': + arg_value = None elif "[" in arg_value: arg_value = arg_value.replace('[', '').replace(']','') arg_value = arg_value.split(',') @@ -205,7 +207,6 @@

Functions

parameters = [] for f in hvsrFunctions: parameters.append(inspect.signature(f).parameters) - #Add argument and options to the parser intermediate_params_list = ['params', 'input', 'hvsr_data', 'hvsr_results'] paramNamesList = [] @@ -225,17 +226,20 @@

Functions

# Add more arguments/options as needed args = parser.parse_args() - + # Map command-line arguments/options to kwargs kwargs = {} for arg_name, arg_value in vars(args).items(): if isinstance(arg_value, str): if "=" in arg_value: arg_value = {arg_value.split('=')[0]: arg_value.split('=')[1]} + if arg_value.lower()=='true': arg_value = True elif arg_value.lower()=='false': arg_value = False + elif arg_value.lower() == 'none': + arg_value = None elif "[" in arg_value: arg_value = arg_value.replace('[', '').replace(']','') arg_value = arg_value.split(',') diff --git a/docs/sprit_hvsr.html b/docs/sprit_hvsr.html index fb04b9a..c618d48 100644 --- a/docs/sprit_hvsr.html +++ b/docs/sprit_hvsr.html @@ -7921,7 +7921,7 @@

Returns

-def input_params(datapath, site='HVSR Site', network='AM', station='RAC84', loc='00', channels=['EHZ', 'EHN', 'EHE'], acq_date='2023-10-11', starttime='00:00:00.00', endtime='23:59:59.999999', tzone='UTC', xcoord=-88.2290526, ycoord=40.1012122, elevation=755, input_crs='EPSG:4326', output_crs='EPSG:4326', elev_unit='feet', depth=0, instrument='Raspberry Shake', metapath='', hvsr_band=[0.4, 40], peak_freq_range=[0.4, 40], verbose=False) +def input_params(datapath, site='HVSR Site', network='AM', station='RAC84', loc='00', channels=['EHZ', 'EHN', 'EHE'], acq_date='2023-10-12', starttime='00:00:00.00', endtime='23:59:59.999999', tzone='UTC', xcoord=-88.2290526, ycoord=40.1012122, elevation=755, input_crs='EPSG:4326', output_crs='EPSG:4326', elev_unit='feet', depth=0, instrument='Raspberry Shake', metapath='', hvsr_band=[0.4, 40], peak_freq_range=[0.4, 40], verbose=False)

Function for designating input parameters for reading in and processing data

diff --git a/pyproject.toml b/pyproject.toml index d99b59b..354614e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "sprit" authors = [{name="Riley Balikian"}, {name="Hongyu Xaio"}] dynamic = ["readme"] license = {file = "LICENSE"} -version="0.1.44" +version="0.1.45" description = "A package for processing and analyzing HVSR (Horizontal to Vertical Spectral Ratio) data" keywords = ["HVSR", "seismic", "horizontal to vertical spectral ratio", "obspy", 'geology', 'geophysics', 'geotechnical'] requires-python = ">=3.9" diff --git a/setup.py b/setup.py index 11d8c0c..38edc82 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ name="sprit", author= "Riley Balikian", author_email = "balikian@illinois.edu", - version="0.1.44", + version="0.1.45", package_data={'sprit': ['resources/*', 'resources/icon/*', 'resources/themes/*', 'resources/themes/forest-dark/*', 'resources/themes/forest-light/*', 'resources/sample_data/*',]}, long_description_content_type="text/markdown", long_description=long_description, diff --git a/sprit/__pycache__/sprit_cli.cpython-311.pyc b/sprit/__pycache__/sprit_cli.cpython-311.pyc index b80cdf091fbef851f2da9b02bb1f8e4a9f290164..b4b810b466608386eddd9d344e85bcc1efea77db 100644 GIT binary patch delta 494 zcmbPd@ZErSIWI340}yOB(nx)?k#`XrC0rGZlPAk^n@*PD){vIUW&&w0VoqVG<Xb~8n|zmBo>6Y{Uv4R&)jeF3C3#et<$)R; zd6F3wCNJgjXIF%1n=H>K&Z?9mvqpKcIIlCK%H(L?cwW^S!PyKc@^e{I)PUm0d9|5A z^jBVaR&}sSNj_OdjmhSG>Vle?3^lw<82cC*8B!R688o#v=kuj8vfX0I%g;;Qe3kz) zBcs;jm4f<=wv%rPW-{tbb{2ByiUGP*1&E7hPM#vv#r#0tf3u448b)~mR@ILTK;j~Y zbO*--&AZ&96Ec?yU*uN3!mav&fp7AA5lhAglQl&x#iXXoPm;eVsB}e8X+hd0L7fYN zIyYn#CdY{8GG5$#N;HMhMIUH>ku``g1QNHniVKP|OX4%iii?UwK%yWw6gh$jJrE%Z mB7}j&FAkgB{FKt1RJ)@1$wlH>LOzU)G9MU_$e79R#0>y+{)B`8 delta 462 zcmexvFwcN@IWI340}ybstEbM~$h(M*ao6SzZ2inkv2P|ja~X1;O%bl)FJmY&o4k=r zbMi8-ipe3|8k60)`IuuXMX| zUB<}3uo{RVpq9UezlOJl&j!ftc{@3nN0nI)sJEIYnNfc7eI9>Cg~|H7vaE_J(rc6^ z2l6^IDo>uu8_%m!BRHEOMQ$!jiYic?kx!c$MC2+M zs825BQy0|8WT@d?!q~^i$dJMi%%G{cc_m*O<7QET%Z!YglV1wzGulj+6v|}Op4=?t z&J_*RuL8uy4U?}3b+LV5V^9cS+?*)9hEblERrLb{khsVp-N7+I^DejOgv_PF7r9lh za04Z{C+mn>GTxY+CTcl(w`e-!h0V%hDU2?9K(mUhK!gF1xW!dmP?T8`pHWs^R3rit x1=&~R03vijgeZs*1`@wGY;yBcN^?@}isB}p7S9s$Vq}#0z<@+XOm>$r000#ga@zm^ diff --git a/sprit/sprit_cli.py b/sprit/sprit_cli.py index 62b9344..41740e8 100644 --- a/sprit/sprit_cli.py +++ b/sprit/sprit_cli.py @@ -49,7 +49,6 @@ def main(): parameters = [] for f in hvsrFunctions: parameters.append(inspect.signature(f).parameters) - #Add argument and options to the parser intermediate_params_list = ['params', 'input', 'hvsr_data', 'hvsr_results'] paramNamesList = [] @@ -69,17 +68,20 @@ def main(): # Add more arguments/options as needed args = parser.parse_args() - + # Map command-line arguments/options to kwargs kwargs = {} for arg_name, arg_value in vars(args).items(): if isinstance(arg_value, str): if "=" in arg_value: arg_value = {arg_value.split('=')[0]: arg_value.split('=')[1]} + if arg_value.lower()=='true': arg_value = True elif arg_value.lower()=='false': arg_value = False + elif arg_value.lower() == 'none': + arg_value = None elif "[" in arg_value: arg_value = arg_value.replace('[', '').replace(']','') arg_value = arg_value.split(',')