From 50d164274702d505617333e18927c744a8c9b428 Mon Sep 17 00:00:00 2001 From: Riley Date: Tue, 3 Oct 2023 16:59:39 -0500 Subject: [PATCH] update vernum, docs, and gen_docs --- conda/meta.yaml | 4 +- docs/generate_docs.py | 13 +- docs/index.html | 41 -- docs/main.html | 124 +++-- docs/sprit_cli.html | 32 +- docs/sprit_gui.html | 463 ++++++++++++------ docs/sprit_hvsr.html | 237 ++++++--- docs/sprit_utils.html | 2 +- pyproject.toml | 2 +- setup.py | 2 +- sprit/__pycache__/__init__.cpython-311.pyc | Bin 1664 -> 1664 bytes sprit/__pycache__/sprit_cli.cpython-311.pyc | Bin 5070 -> 5698 bytes sprit/__pycache__/sprit_gui.cpython-311.pyc | Bin 200324 -> 200324 bytes sprit/__pycache__/sprit_hvsr.cpython-311.pyc | Bin 315639 -> 315639 bytes sprit/__pycache__/sprit_utils.cpython-311.pyc | Bin 17183 -> 17183 bytes 15 files changed, 610 insertions(+), 310 deletions(-) delete mode 100644 docs/index.html diff --git a/conda/meta.yaml b/conda/meta.yaml index fbb226e..0f7c029 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -1,10 +1,10 @@ package: name: sprit - version: 0.1.37 + version: 0.1.38 source: git_url: https://github.com/RJbalikian/SPRIT-HVSR - git_tag: v0.1.37 + git_tag: v0.1.38 build: number: 0 diff --git a/docs/generate_docs.py b/docs/generate_docs.py index 62f17f5..1240c6b 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.37' +release_version= '0.1.38' currentDir = pathlib.Path((__file__)).parent docsDir = currentDir @@ -22,7 +22,7 @@ pyinstallerGUI = currentDir.joinpath('sprit_gui_COPY.py') # Set the package name, subdirectory, and output directory -subdir = '.\sprit' +subdir = './sprit' output_dir = 'docs' venvPath = pathlib.Path(sys.executable).parent.parent @@ -52,8 +52,9 @@ break src_path = pathlib.Path(subdir) -trg_path = src_path.parent # this ends up being main repo folder, usually - +trg_path = src_path.parent.joinpath(output_dir) # this ends up being main repo folder, usually +print(src_path.absolute()) +print(trg_path.absolute()) #Move items back into the main docs folder keepList = ['generate_docs.py', 'conf.py', 'requirements.txt', 'wiki', 'pyinstaller'] for t in trg_path.iterdir(): @@ -88,7 +89,7 @@ file = file.rename(destFilePath) keepList.append(destFilePath.name) if file.name=='index.html': - mainhtmlFPath = file.parent.parent.joinpath('main.html') + mainhtmlFPath = file.parent.joinpath('main.html') if mainhtmlFPath.is_file(): os.remove(mainhtmlFPath) file.rename(mainhtmlFPath) @@ -169,7 +170,7 @@ newVerText = r'version: '+release_version cFileText = re.sub(verText, newVerText, cFileText, flags=re.DOTALL) - verText = r'git_tag:\s+\d+\.\d+\.\d+[^\n]*' + verText = r'git_tag:\s+v+\d+\.\d+\.\d+[^\n]*' newVerText = r'git_tag: v'+release_version cFileText = re.sub(verText, newVerText, cFileText, flags=re.DOTALL) diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 12be7eb..0000000 --- a/docs/index.html +++ /dev/null @@ -1,41 +0,0 @@ -

SPRĪT

-

SpRĪT (HVSR): Spectral Ratio Investigation Toolset for basic Horizontal Vertical Spectral Ratio processing, using any data format readable by the Obspy python package.

-

Introduction

-

The Horizontal to Vertical Spectral Ratio (HVSR) technique is a method used to analyze ambient seismic noise to calculate the dominant frequency at a site.

-

This package will allow ambient seismic data to be read in the most common seismic data formats, and will perform Horizontal Vertical Spectral Ratio (HVSR) analysis on the data. H/V analysis was standardized and popularized by the Site EffectS assessment using AMbient Excitations (SESAME) project, with a comprehensive final report issued in 2003.1 This SESAME project and its J-SESAME pacakge were crucial in the developing of the HVSR technique, and the outputs aided in the development of this software package.

-

This python package is built in large part off the Incorporated Research Institutions in Seismology (IRIS) Horizontal to Vertical Spectral Ratio (HVSR) processing package.2 Specifically, the computeHVSR.py tools that enable the ability to rank HVSR peaks, calculate data quality and peak quality, and the combining of the horizontal components was adapted directly from that package. Because the SpRĪT package is intended to be used to analyze data from rapid field data acquisitions (less than an hour per site), much of the IRIS package was adapted from daily to HV curve calculations to sub-hourly and even sub-minute HV calculations. Because there is limited data, there is no baseline to compare to, so that element is excluded from this package.

-

That version is intended to read data from the IRIS Data Management Center (DMC) MUSTANG online service,3 which is a toolbox that provides processes for enabling data quality analysis services to data archived in the DMC. For example, a simple service query can extract power spectral density estimates, noise spectrograms, H/V plots, etc.

-

For guidelines on acquisition, processing, and interpration of H/V data, see: http://sesame.geopsy.org/Papers/HV_User_Guidelines.pdf.

-

Documentation

- -

Dependencies

-

Aside from the modules in the python standard library, the following package dependencies must be installed in your environment for this package to work

- -

References

- -

Considerations

-

Summary from SESAME Project (from https://www.iitk.ac.in/nicee/wcee/article/13_2207.pdf): -In very brief, the main learnings may be summarized as follows:

- \ No newline at end of file diff --git a/docs/main.html b/docs/main.html index de32d58..244f9de 100644 --- a/docs/main.html +++ b/docs/main.html @@ -405,11 +405,14 @@

Raises

#Collect warnings that happened before we got to the error if w: hasWarnings = True - for warning in w: - warning_category = type(warning.message).__name__.title().replace('warning','Warning') - warning_message = str(warning.message) + 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_message}') + messageList.append(f'{warning_category} ({warning_lineNo}): {warning_message}') return messageList # use functools.wraps to preserve the original function's metadata @@ -439,7 +442,8 @@

Raises

warningMessage = "WARNING:" for msg in messageList: warningMessage = "\n {}".format(msg) - + + print(warningMessage) messagebox.showwarning(title='WARNINGS', message=warningMessage) except Exception as e: @@ -464,9 +468,10 @@

Raises

for addMsg in warningMessageList: fullErrorMessage = "\n{}\n {}".format(fullErrorMessage, addMsg) + print(fullErrorMessage) messagebox.showerror(title=f'ERROR ({error_category})', message=fullErrorMessage) - + # return the result of the function or the error/warning messages and categories return result # return the wrapper function @@ -974,8 +979,8 @@

Parameters

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 = [] @@ -1182,6 +1187,38 @@

Parameters

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() @@ -1394,7 +1431,7 @@

Returns

Parameters

params : dict, HVSRData object, or HVSRBatch object
-
Dictionary containing all the parameters and other data of interest (stream and paz, for example)
+
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
@@ -1426,7 +1463,7 @@

Returns

Parameters ---------- params : dict, HVSRData object, or HVSRBatch object - Dictionary containing all the parameters and other data of interest (stream and paz, for example) + 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 @@ -1570,15 +1607,15 @@

Returns

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]), - int(np.where(EArr == cTime)[0]), - int(np.where(NArr == cTime)[0])]) + + 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: @@ -1643,9 +1680,9 @@

Returns

hvsrDF['Use'] = True for gap in params['ppsds']['Z']['times_gaps']: - hvsrDF['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) hvsrDF.set_index('TimesProcessed', inplace=True) params['hvsr_df'] = hvsrDF @@ -2145,10 +2182,17 @@

Returns

gui_root.destroy() if sys.platform == 'linux': - 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.') + 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() - icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) - gui_root.iconbitmap(icon_path) + try: + icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon.png')) + gui_root.iconphoto(False, tk.PhotoImage(file=icon_path)) + #gui_root.iconbitmap(icon_path) + except Exception as e: + print(e) + print('icon not loaded') SPRIT_App(master=gui_root) #Open the app with a tk.Tk root gui_root.protocol("WM_DELETE_WINDOW", on_gui_closing) @@ -2219,7 +2263,7 @@

Returns

-def input_params(datapath, site='HVSR Site', network='AM', station='RAC84', loc='00', channels=['EHZ', 'EHN', 'EHE'], acq_date='2023-10-02', 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-03', 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

@@ -2898,12 +2942,14 @@

Returns

currTimesUsed={} hvsrDF = params['hvsr_df'] - - for k in ppsds: + 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 - input_ppsds = np.stack(currPPSDs) + used_ppsds = np.stack(currPPSDs) + #if reasmpling has been selected if resample is True or type(resample) is int: if resample is True: @@ -3049,10 +3095,14 @@

Returns

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 - hvsr_out['hvsr_df'][bool_col] = ((avg_stdT - (std_stdT * outlier_curve_std)) < (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) & \ - ((avg_stdT + (std_stdT * outlier_curve_std)) > (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) + 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 = [] @@ -3086,7 +3136,6 @@

Returns

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']) @@ -3405,10 +3454,10 @@

Returns

if trEndTime < trStartTime and comp_end==comp_start: gap = [trEndTime,trStartTime] - - output['hvsr_df']['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + hvsrDF= output['hvsr_df'] + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) trEndTime = trace.stats.endtime @@ -3523,7 +3572,7 @@

Raises

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} @@ -3587,7 +3636,18 @@

Raises

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: + except Exception as e: + if verbose: + 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} diff --git a/docs/sprit_cli.html b/docs/sprit_cli.html index 0426110..3ff4eb3 100644 --- a/docs/sprit_cli.html +++ b/docs/sprit_cli.html @@ -44,7 +44,7 @@

Module sprit.sprit_cli

try: import sprit # When distributed except: - #import sprit_hvsr as sprit #When testing + import sprit_hvsr as sprit #When testing pass def get_param_docstring(func, param_name): @@ -119,8 +119,19 @@

Module sprit.sprit_cli

arg_value = arg_value.split(',') kwargs[arg_name] = arg_value - for key, value in kwargs.items(): - print(key, value) + if not kwargs['verbose']: + print("Running sprit.run() with the following arguments (use --verbose for more information):") + print(f"sprit.run(", end='') + for key, value in kwargs.items(): + if 'kwargs' in str(key): + pass + else: + if type(value) is str: + print(f"{key}='{value}'",end=', ') + else: + print(f"{key}={value}",end=', ') + print('**ppsd_kwargs, **kwargs', end='') + print(')') #print(kwargs['kwargs']) # Call the sprit.run function with the generated kwargs @@ -228,8 +239,19 @@

Functions

arg_value = arg_value.split(',') kwargs[arg_name] = arg_value - for key, value in kwargs.items(): - print(key, value) + if not kwargs['verbose']: + print("Running sprit.run() with the following arguments (use --verbose for more information):") + print(f"sprit.run(", end='') + for key, value in kwargs.items(): + if 'kwargs' in str(key): + pass + else: + if type(value) is str: + print(f"{key}='{value}'",end=', ') + else: + print(f"{key}={value}",end=', ') + print('**ppsd_kwargs, **kwargs', end='') + print(')') #print(kwargs['kwargs']) # Call the sprit.run function with the generated kwargs diff --git a/docs/sprit_gui.html b/docs/sprit_gui.html index 1779978..79ce033 100644 --- a/docs/sprit_gui.html +++ b/docs/sprit_gui.html @@ -32,6 +32,7 @@

Module sprit.sprit_gui

import datetime import functools +import linecache import os import pathlib import pkg_resources @@ -56,8 +57,8 @@

Module sprit.sprit_gui

from sprit import sprit_utils from sprit import sprit_hvsr except: #For local testing - #import sprit_hvsr - #import sprit_utils + import sprit_hvsr + import sprit_utils pass #Decorator that catches errors and warnings (to be modified later for gui) @@ -68,11 +69,14 @@

Module sprit.sprit_gui

#Collect warnings that happened before we got to the error if w: hasWarnings = True - for warning in w: - warning_category = type(warning.message).__name__.title().replace('warning','Warning') - warning_message = str(warning.message) + 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_message}') + messageList.append(f'{warning_category} ({warning_lineNo}): {warning_message}') return messageList # use functools.wraps to preserve the original function's metadata @@ -102,7 +106,8 @@

Module sprit.sprit_gui

warningMessage = "WARNING:" for msg in messageList: warningMessage = "\n {}".format(msg) - + + print(warningMessage) messagebox.showwarning(title='WARNINGS', message=warningMessage) except Exception as e: @@ -127,9 +132,10 @@

Module sprit.sprit_gui

for addMsg in warningMessageList: fullErrorMessage = "\n{}\n {}".format(fullErrorMessage, addMsg) + print(fullErrorMessage) messagebox.showerror(title=f'ERROR ({error_category})', message=fullErrorMessage) - + # return the result of the function or the error/warning messages and categories return result # return the wrapper function @@ -320,8 +326,38 @@

Module sprit.sprit_gui

else: self.fpath = self.fpath[0] - self.params = sprit_hvsr.batch_data_read(input_data=self.fpath, batch_type=batchType) - self.hvsr_data = self.params + self.params = sprit_hvsr.input_params(datapath=self.fpath, + metapath = self.meta_path.get(), + site=self.site_name.get(), + network=self.network.get(), + station=self.station.get(), + loc=self.location.get(), + channels=[self.z_channel.get(), self.n_channel.get(), self.e_channel.get()], + acq_date = self.starttime.date(), + starttime = self.starttime, + endtime = self.endtime, + tzone = 'UTC', #Will always be converted to UTC before we get to this point when using gui + xcoord = self.x.get(), + ycoord = self.y.get(), + elevation = self.z.get(), + input_crs= self.input_crs.get(), + output_crs= self.output_crs.get(), + elev_unit= self.elev_unit.get(), + instrument = self.instrumentSel.get(), + hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()] ) + + if self.trim_dir.get()=='': + trimDir=None + else: + trimDir=self.trim_dir.get() + + self.hvsr_data = sprit_hvsr.fetch_data(params=self.params, + source=self.file_source.get(), + trim_dir=trimDir, + export_format=self.export_format.get(), + detrend=self.detrend.get(), + detrend_order=self.detrend_order.get()) + self.site_options = self.hvsr_data.sites firstSite = self.hvsr_data[list(self.hvsr_data.keys())[0]] @@ -391,51 +427,50 @@

Module sprit.sprit_gui

self.tab_control.select(self.preview_data_tab) def report_results(hvsr_results): - - self.curveTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['Lw'][:-1]) - self.curveTest1Result.configure(text=hvsr_results['Best Peak']['Report']['Lw'][-1]) + self.curveTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['Lw'][:-1]) + self.curveTest1Result.configure(text=hvsr_results['BestPeak']['Report']['Lw'][-1]) - self.curveTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['Nc'][:-1]) - self.curveTest2Result.configure(text=hvsr_results['Best Peak']['Report']['Nc'][-1]) + self.curveTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['Nc'][:-1]) + self.curveTest2Result.configure(text=hvsr_results['BestPeak']['Report']['Nc'][-1]) - self.curveTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][:-1]) - self.curveTest3Result.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][-1]) + self.curveTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][:-1]) + self.curveTest3Result.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][-1]) - curvePass = (hvsr_results['Best Peak']['Pass List']['Window Length Freq.'] + - hvsr_results['Best Peak']['Pass List']['Significant Cycles']+ - hvsr_results['Best Peak']['Pass List']['Low Curve StDev. over time']) > 2 + curvePass = (hvsr_results['BestPeak']['PassList']['WindowLengthFreq.'] + + hvsr_results['BestPeak']['PassList']['SignificantCycles']+ + hvsr_results['BestPeak']['PassList']['LowCurveStDevOverTime']) > 2 if curvePass: self.totalCurveResult.configure(text=sprit_utils.check_mark(), font=("TkDefaultFont", 16, "bold"), foreground='green') else: self.totalCurveResult.configure(text=sprit_utils.x_mark(), font=("TkDefaultFont", 16, "bold"), foreground='red') - self.peakTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][:-1]) - self.peakTest1Result.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][-1]) + self.peakTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][:-1]) + self.peakTest1Result.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][-1]) - self.peakTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][:-1]) - self.peakTest2Result.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][-1]) + self.peakTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][:-1]) + self.peakTest2Result.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][-1]) - self.peakTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['A0'][:-1]) - self.peakTest3Result.configure(text=hvsr_results['Best Peak']['Report']['A0'][-1]) + self.peakTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['A0'][:-1]) + self.peakTest3Result.configure(text=hvsr_results['BestPeak']['Report']['A0'][-1]) - self.peakTest4ResultText.configure(text=hvsr_results['Best Peak']['Report']['P-'][:5] + ' and ' +hvsr_results['Best Peak']['Report']['P+'][:-1]) - if hvsr_results['Best Peak']['Pass List']['Freq. Stability']: + self.peakTest4ResultText.configure(text=hvsr_results['BestPeak']['Report']['P-'][:5] + ' and ' +hvsr_results['BestPeak']['Report']['P+'][:-1]) + if hvsr_results['BestPeak']['PassList']['FreqStability']: self.peakTest4Result.configure(text=sprit_utils.check_mark()) else: self.peakTest4Result.configure(text=sprit_utils.x_mark()) - self.peakTest5ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sf'][:-1]) - self.peakTest5Result.configure(text=hvsr_results['Best Peak']['Report']['Sf'][-1]) + self.peakTest5ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sf'][:-1]) + self.peakTest5Result.configure(text=hvsr_results['BestPeak']['Report']['Sf'][-1]) - self.peakTest6ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sa'][:-1]) - self.peakTest6Result.configure(text=hvsr_results['Best Peak']['Report']['Sa'][-1]) - - peakPass = (hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Below'] + - hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Above']+ - hvsr_results['Best Peak']['Pass List']['Peak Amp. Clarity']+ - hvsr_results['Best Peak']['Pass List']['Freq. Stability']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (freq. std)']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (amp. std)']) >= 5 + self.peakTest6ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sa'][:-1]) + self.peakTest6Result.configure(text=hvsr_results['BestPeak']['Report']['Sa'][-1]) + + peakPass = (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']) >= 5 if peakPass: self.totalPeakResult.configure(text='✔', font=("TkDefaultFont", 16, "bold"), foreground='green') else: @@ -456,34 +491,39 @@

Module sprit.sprit_gui

if self.data_read == False: read_data() + #Make this an option + #self.hvsr_data = sprit_hvsr.remove_noise(self.hvsr_data, remove_method='auto') + self.hvsr_data = plot_noise_windows(self.hvsr_data) - + self.hvsr_data = sprit_hvsr.generate_ppsds(params=self.hvsr_data, - ppsd_length=self.ppsd_length.get(), - overlap=self.overlap.get(), - period_step_octaves=self.perStepOct.get(), - remove_outliers=self.remove_outliers.get(), - outlier_std=self.outlier_std.get(), - skip_on_gaps=self.skip_on_gaps.get(), - db_bins=self.db_bins, - period_limits=self.period_limits, - period_smoothing_width_octaves=self.perSmoothWidthOct.get(), - special_handling=special_handling + remove_outliers=self.remove_outliers.get(), + outlier_std=self.outlier_std.get(), + + ppsd_length=self.ppsd_length.get(), + overlap=self.overlap.get(), + period_step_octaves=self.perStepOct.get(), + skip_on_gaps=self.skip_on_gaps.get(), + db_bins=self.db_bins, + period_limits=self.period_limits, + period_smoothing_width_octaves=self.perSmoothWidthOct.get(), + special_handling=special_handling, verbose=True ) + self.hvsr_results = sprit_hvsr.process_hvsr(params=self.hvsr_data, method=self.method_ind, smooth=self.hvsmooth_param, freq_smooth=self.freq_smooth.get(), f_smooth_width=self.fSmoothWidth.get(), - resample=self.hvresample_int, - remove_outlier_curves=self.outlierRembool.get(), + resample=self.hvresample_int, outlier_curve_std=self.outlierRemStDev.get()) self.hvsr_results = sprit_hvsr.check_peaks(hvsr_data=self.hvsr_results, hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()], - peak_water_level=self.peak_water_level) + peak_freq_range=[self.hvsrBand_min.get(), self.hvsrBand_max.get()]) + print(type(self.hvsr_results)) if isinstance(self.hvsr_results, sprit_hvsr.HVSRData): report_results(self.hvsr_results) #self.results_siteSelectFrame.grid_forget() @@ -1447,7 +1487,10 @@

Module sprit.sprit_gui

if i==0: self.fig_noise, self.ax_noise, self.noise_windows_line_artists, self.noise_windows_window_artists = sprit_hvsr._get_removed_windows(input=hv_data, fig=self.fig_noise, ax=self.ax_noise, existing_xWindows=self.xWindows, time_type='matplotlib') self.fig_noise.canvas.draw() - + + if batch_data is None: + hvsr_data = hvsr_data['SITENAME'] + return hvsr_data self.fig_noise.canvas.draw() @@ -2556,6 +2599,7 @@

Module sprit.sprit_gui

# RESULTS TAB self.results_tab = ttk.Frame(self.tab_control) + self.hvsr_results = {'site':''}#Just initialize for now # Create the Batch Site selection LabelFrame self.results_siteSelectFrame = ttk.LabelFrame(self.results_tab, text="HVSR Results") @@ -2567,9 +2611,13 @@

Module sprit.sprit_gui

report_results(self.hvsr_results[sitename]) except: warnings.warn(f"Site {sitename} does not exist", UserWarning) - - self.site_options = [''] - self.selectedSite = tk.StringVar(value=self.site_options[0]) + + if isinstance(self.hvsr_results, sprit_hvsr.HVSRBatch): + sites = self.hvsr_results.sites + else: + sites = [self.hvsr_results['site']] + self.site_options = sites + self.selectedSite = tk.StringVar(value=sites[0]) self.site_dropdown = ttk.Combobox(self.results_siteSelectFrame, textvariable=self.selectedSite, values=self.site_options, validate='focusout', validatecommand=on_site_select) self.site_dropdown.config(width=30) self.results_siteSelectLabel.grid(row=0, column=0, columnspan=1, sticky='ew') @@ -2809,8 +2857,12 @@

Module sprit.sprit_gui

if __name__ == "__main__": root = tk.Tk() - icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) - root.iconbitmap(icon_path) + try: + icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon.png')) + #icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) + root.iconphoto(False, tk.PhotoImage(file=icon_path)) + except Exception as e: + print("ICON NOT LOADED",e) app = SPRIT_App(root) @@ -2841,11 +2893,14 @@

Functions

#Collect warnings that happened before we got to the error if w: hasWarnings = True - for warning in w: - warning_category = type(warning.message).__name__.title().replace('warning','Warning') - warning_message = str(warning.message) + 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_message}') + messageList.append(f'{warning_category} ({warning_lineNo}): {warning_message}') return messageList # use functools.wraps to preserve the original function's metadata @@ -2875,7 +2930,8 @@

Functions

warningMessage = "WARNING:" for msg in messageList: warningMessage = "\n {}".format(msg) - + + print(warningMessage) messagebox.showwarning(title='WARNINGS', message=warningMessage) except Exception as e: @@ -2900,9 +2956,10 @@

Functions

for addMsg in warningMessageList: fullErrorMessage = "\n{}\n {}".format(fullErrorMessage, addMsg) + print(fullErrorMessage) messagebox.showerror(title=f'ERROR ({error_category})', message=fullErrorMessage) - + # return the result of the function or the error/warning messages and categories return result # return the wrapper function @@ -3124,8 +3181,38 @@

Classes

else: self.fpath = self.fpath[0] - self.params = sprit_hvsr.batch_data_read(input_data=self.fpath, batch_type=batchType) - self.hvsr_data = self.params + self.params = sprit_hvsr.input_params(datapath=self.fpath, + metapath = self.meta_path.get(), + site=self.site_name.get(), + network=self.network.get(), + station=self.station.get(), + loc=self.location.get(), + channels=[self.z_channel.get(), self.n_channel.get(), self.e_channel.get()], + acq_date = self.starttime.date(), + starttime = self.starttime, + endtime = self.endtime, + tzone = 'UTC', #Will always be converted to UTC before we get to this point when using gui + xcoord = self.x.get(), + ycoord = self.y.get(), + elevation = self.z.get(), + input_crs= self.input_crs.get(), + output_crs= self.output_crs.get(), + elev_unit= self.elev_unit.get(), + instrument = self.instrumentSel.get(), + hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()] ) + + if self.trim_dir.get()=='': + trimDir=None + else: + trimDir=self.trim_dir.get() + + self.hvsr_data = sprit_hvsr.fetch_data(params=self.params, + source=self.file_source.get(), + trim_dir=trimDir, + export_format=self.export_format.get(), + detrend=self.detrend.get(), + detrend_order=self.detrend_order.get()) + self.site_options = self.hvsr_data.sites firstSite = self.hvsr_data[list(self.hvsr_data.keys())[0]] @@ -3195,51 +3282,50 @@

Classes

self.tab_control.select(self.preview_data_tab) def report_results(hvsr_results): - - self.curveTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['Lw'][:-1]) - self.curveTest1Result.configure(text=hvsr_results['Best Peak']['Report']['Lw'][-1]) + self.curveTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['Lw'][:-1]) + self.curveTest1Result.configure(text=hvsr_results['BestPeak']['Report']['Lw'][-1]) - self.curveTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['Nc'][:-1]) - self.curveTest2Result.configure(text=hvsr_results['Best Peak']['Report']['Nc'][-1]) + self.curveTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['Nc'][:-1]) + self.curveTest2Result.configure(text=hvsr_results['BestPeak']['Report']['Nc'][-1]) - self.curveTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][:-1]) - self.curveTest3Result.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][-1]) + self.curveTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][:-1]) + self.curveTest3Result.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][-1]) - curvePass = (hvsr_results['Best Peak']['Pass List']['Window Length Freq.'] + - hvsr_results['Best Peak']['Pass List']['Significant Cycles']+ - hvsr_results['Best Peak']['Pass List']['Low Curve StDev. over time']) > 2 + curvePass = (hvsr_results['BestPeak']['PassList']['WindowLengthFreq.'] + + hvsr_results['BestPeak']['PassList']['SignificantCycles']+ + hvsr_results['BestPeak']['PassList']['LowCurveStDevOverTime']) > 2 if curvePass: self.totalCurveResult.configure(text=sprit_utils.check_mark(), font=("TkDefaultFont", 16, "bold"), foreground='green') else: self.totalCurveResult.configure(text=sprit_utils.x_mark(), font=("TkDefaultFont", 16, "bold"), foreground='red') - self.peakTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][:-1]) - self.peakTest1Result.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][-1]) + self.peakTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][:-1]) + self.peakTest1Result.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][-1]) - self.peakTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][:-1]) - self.peakTest2Result.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][-1]) + self.peakTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][:-1]) + self.peakTest2Result.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][-1]) - self.peakTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['A0'][:-1]) - self.peakTest3Result.configure(text=hvsr_results['Best Peak']['Report']['A0'][-1]) + self.peakTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['A0'][:-1]) + self.peakTest3Result.configure(text=hvsr_results['BestPeak']['Report']['A0'][-1]) - self.peakTest4ResultText.configure(text=hvsr_results['Best Peak']['Report']['P-'][:5] + ' and ' +hvsr_results['Best Peak']['Report']['P+'][:-1]) - if hvsr_results['Best Peak']['Pass List']['Freq. Stability']: + self.peakTest4ResultText.configure(text=hvsr_results['BestPeak']['Report']['P-'][:5] + ' and ' +hvsr_results['BestPeak']['Report']['P+'][:-1]) + if hvsr_results['BestPeak']['PassList']['FreqStability']: self.peakTest4Result.configure(text=sprit_utils.check_mark()) else: self.peakTest4Result.configure(text=sprit_utils.x_mark()) - self.peakTest5ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sf'][:-1]) - self.peakTest5Result.configure(text=hvsr_results['Best Peak']['Report']['Sf'][-1]) + self.peakTest5ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sf'][:-1]) + self.peakTest5Result.configure(text=hvsr_results['BestPeak']['Report']['Sf'][-1]) - self.peakTest6ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sa'][:-1]) - self.peakTest6Result.configure(text=hvsr_results['Best Peak']['Report']['Sa'][-1]) - - peakPass = (hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Below'] + - hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Above']+ - hvsr_results['Best Peak']['Pass List']['Peak Amp. Clarity']+ - hvsr_results['Best Peak']['Pass List']['Freq. Stability']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (freq. std)']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (amp. std)']) >= 5 + self.peakTest6ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sa'][:-1]) + self.peakTest6Result.configure(text=hvsr_results['BestPeak']['Report']['Sa'][-1]) + + peakPass = (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']) >= 5 if peakPass: self.totalPeakResult.configure(text='✔', font=("TkDefaultFont", 16, "bold"), foreground='green') else: @@ -3260,34 +3346,39 @@

Classes

if self.data_read == False: read_data() + #Make this an option + #self.hvsr_data = sprit_hvsr.remove_noise(self.hvsr_data, remove_method='auto') + self.hvsr_data = plot_noise_windows(self.hvsr_data) - + self.hvsr_data = sprit_hvsr.generate_ppsds(params=self.hvsr_data, - ppsd_length=self.ppsd_length.get(), - overlap=self.overlap.get(), - period_step_octaves=self.perStepOct.get(), - remove_outliers=self.remove_outliers.get(), - outlier_std=self.outlier_std.get(), - skip_on_gaps=self.skip_on_gaps.get(), - db_bins=self.db_bins, - period_limits=self.period_limits, - period_smoothing_width_octaves=self.perSmoothWidthOct.get(), - special_handling=special_handling + remove_outliers=self.remove_outliers.get(), + outlier_std=self.outlier_std.get(), + + ppsd_length=self.ppsd_length.get(), + overlap=self.overlap.get(), + period_step_octaves=self.perStepOct.get(), + skip_on_gaps=self.skip_on_gaps.get(), + db_bins=self.db_bins, + period_limits=self.period_limits, + period_smoothing_width_octaves=self.perSmoothWidthOct.get(), + special_handling=special_handling, verbose=True ) + self.hvsr_results = sprit_hvsr.process_hvsr(params=self.hvsr_data, method=self.method_ind, smooth=self.hvsmooth_param, freq_smooth=self.freq_smooth.get(), f_smooth_width=self.fSmoothWidth.get(), - resample=self.hvresample_int, - remove_outlier_curves=self.outlierRembool.get(), + resample=self.hvresample_int, outlier_curve_std=self.outlierRemStDev.get()) self.hvsr_results = sprit_hvsr.check_peaks(hvsr_data=self.hvsr_results, hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()], - peak_water_level=self.peak_water_level) + peak_freq_range=[self.hvsrBand_min.get(), self.hvsrBand_max.get()]) + print(type(self.hvsr_results)) if isinstance(self.hvsr_results, sprit_hvsr.HVSRData): report_results(self.hvsr_results) #self.results_siteSelectFrame.grid_forget() @@ -4251,7 +4342,10 @@

Classes

if i==0: self.fig_noise, self.ax_noise, self.noise_windows_line_artists, self.noise_windows_window_artists = sprit_hvsr._get_removed_windows(input=hv_data, fig=self.fig_noise, ax=self.ax_noise, existing_xWindows=self.xWindows, time_type='matplotlib') self.fig_noise.canvas.draw() - + + if batch_data is None: + hvsr_data = hvsr_data['SITENAME'] + return hvsr_data self.fig_noise.canvas.draw() @@ -5360,6 +5454,7 @@

Classes

# RESULTS TAB self.results_tab = ttk.Frame(self.tab_control) + self.hvsr_results = {'site':''}#Just initialize for now # Create the Batch Site selection LabelFrame self.results_siteSelectFrame = ttk.LabelFrame(self.results_tab, text="HVSR Results") @@ -5371,9 +5466,13 @@

Classes

report_results(self.hvsr_results[sitename]) except: warnings.warn(f"Site {sitename} does not exist", UserWarning) - - self.site_options = [''] - self.selectedSite = tk.StringVar(value=self.site_options[0]) + + if isinstance(self.hvsr_results, sprit_hvsr.HVSRBatch): + sites = self.hvsr_results.sites + else: + sites = [self.hvsr_results['site']] + self.site_options = sites + self.selectedSite = tk.StringVar(value=sites[0]) self.site_dropdown = ttk.Combobox(self.results_siteSelectFrame, textvariable=self.selectedSite, values=self.site_options, validate='focusout', validatecommand=on_site_select) self.site_dropdown.config(width=30) self.results_siteSelectLabel.grid(row=0, column=0, columnspan=1, sticky='ew') @@ -5758,8 +5857,38 @@

Methods

else: self.fpath = self.fpath[0] - self.params = sprit_hvsr.batch_data_read(input_data=self.fpath, batch_type=batchType) - self.hvsr_data = self.params + self.params = sprit_hvsr.input_params(datapath=self.fpath, + metapath = self.meta_path.get(), + site=self.site_name.get(), + network=self.network.get(), + station=self.station.get(), + loc=self.location.get(), + channels=[self.z_channel.get(), self.n_channel.get(), self.e_channel.get()], + acq_date = self.starttime.date(), + starttime = self.starttime, + endtime = self.endtime, + tzone = 'UTC', #Will always be converted to UTC before we get to this point when using gui + xcoord = self.x.get(), + ycoord = self.y.get(), + elevation = self.z.get(), + input_crs= self.input_crs.get(), + output_crs= self.output_crs.get(), + elev_unit= self.elev_unit.get(), + instrument = self.instrumentSel.get(), + hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()] ) + + if self.trim_dir.get()=='': + trimDir=None + else: + trimDir=self.trim_dir.get() + + self.hvsr_data = sprit_hvsr.fetch_data(params=self.params, + source=self.file_source.get(), + trim_dir=trimDir, + export_format=self.export_format.get(), + detrend=self.detrend.get(), + detrend_order=self.detrend_order.get()) + self.site_options = self.hvsr_data.sites firstSite = self.hvsr_data[list(self.hvsr_data.keys())[0]] @@ -5829,51 +5958,50 @@

Methods

self.tab_control.select(self.preview_data_tab) def report_results(hvsr_results): - - self.curveTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['Lw'][:-1]) - self.curveTest1Result.configure(text=hvsr_results['Best Peak']['Report']['Lw'][-1]) + self.curveTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['Lw'][:-1]) + self.curveTest1Result.configure(text=hvsr_results['BestPeak']['Report']['Lw'][-1]) - self.curveTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['Nc'][:-1]) - self.curveTest2Result.configure(text=hvsr_results['Best Peak']['Report']['Nc'][-1]) + self.curveTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['Nc'][:-1]) + self.curveTest2Result.configure(text=hvsr_results['BestPeak']['Report']['Nc'][-1]) - self.curveTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][:-1]) - self.curveTest3Result.configure(text=hvsr_results['Best Peak']['Report']['σ_A(f)'][-1]) + self.curveTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][:-1]) + self.curveTest3Result.configure(text=hvsr_results['BestPeak']['Report']['σ_A(f)'][-1]) - curvePass = (hvsr_results['Best Peak']['Pass List']['Window Length Freq.'] + - hvsr_results['Best Peak']['Pass List']['Significant Cycles']+ - hvsr_results['Best Peak']['Pass List']['Low Curve StDev. over time']) > 2 + curvePass = (hvsr_results['BestPeak']['PassList']['WindowLengthFreq.'] + + hvsr_results['BestPeak']['PassList']['SignificantCycles']+ + hvsr_results['BestPeak']['PassList']['LowCurveStDevOverTime']) > 2 if curvePass: self.totalCurveResult.configure(text=sprit_utils.check_mark(), font=("TkDefaultFont", 16, "bold"), foreground='green') else: self.totalCurveResult.configure(text=sprit_utils.x_mark(), font=("TkDefaultFont", 16, "bold"), foreground='red') - self.peakTest1ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][:-1]) - self.peakTest1Result.configure(text=hvsr_results['Best Peak']['Report']['A(f-)'][-1]) + self.peakTest1ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][:-1]) + self.peakTest1Result.configure(text=hvsr_results['BestPeak']['Report']['A(f-)'][-1]) - self.peakTest2ResultText.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][:-1]) - self.peakTest2Result.configure(text=hvsr_results['Best Peak']['Report']['A(f+)'][-1]) + self.peakTest2ResultText.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][:-1]) + self.peakTest2Result.configure(text=hvsr_results['BestPeak']['Report']['A(f+)'][-1]) - self.peakTest3ResultText.configure(text=hvsr_results['Best Peak']['Report']['A0'][:-1]) - self.peakTest3Result.configure(text=hvsr_results['Best Peak']['Report']['A0'][-1]) + self.peakTest3ResultText.configure(text=hvsr_results['BestPeak']['Report']['A0'][:-1]) + self.peakTest3Result.configure(text=hvsr_results['BestPeak']['Report']['A0'][-1]) - self.peakTest4ResultText.configure(text=hvsr_results['Best Peak']['Report']['P-'][:5] + ' and ' +hvsr_results['Best Peak']['Report']['P+'][:-1]) - if hvsr_results['Best Peak']['Pass List']['Freq. Stability']: + self.peakTest4ResultText.configure(text=hvsr_results['BestPeak']['Report']['P-'][:5] + ' and ' +hvsr_results['BestPeak']['Report']['P+'][:-1]) + if hvsr_results['BestPeak']['PassList']['FreqStability']: self.peakTest4Result.configure(text=sprit_utils.check_mark()) else: self.peakTest4Result.configure(text=sprit_utils.x_mark()) - self.peakTest5ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sf'][:-1]) - self.peakTest5Result.configure(text=hvsr_results['Best Peak']['Report']['Sf'][-1]) + self.peakTest5ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sf'][:-1]) + self.peakTest5Result.configure(text=hvsr_results['BestPeak']['Report']['Sf'][-1]) - self.peakTest6ResultText.configure(text=hvsr_results['Best Peak']['Report']['Sa'][:-1]) - self.peakTest6Result.configure(text=hvsr_results['Best Peak']['Report']['Sa'][-1]) + self.peakTest6ResultText.configure(text=hvsr_results['BestPeak']['Report']['Sa'][:-1]) + self.peakTest6Result.configure(text=hvsr_results['BestPeak']['Report']['Sa'][-1]) - peakPass = (hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Below'] + - hvsr_results['Best Peak']['Pass List']['Peak Freq. Clarity Above']+ - hvsr_results['Best Peak']['Pass List']['Peak Amp. Clarity']+ - hvsr_results['Best Peak']['Pass List']['Freq. Stability']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (freq. std)']+ - hvsr_results['Best Peak']['Pass List']['Peak Stability (amp. std)']) >= 5 + peakPass = (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']) >= 5 if peakPass: self.totalPeakResult.configure(text='✔', font=("TkDefaultFont", 16, "bold"), foreground='green') else: @@ -5894,34 +6022,39 @@

Methods

if self.data_read == False: read_data() + #Make this an option + #self.hvsr_data = sprit_hvsr.remove_noise(self.hvsr_data, remove_method='auto') + self.hvsr_data = plot_noise_windows(self.hvsr_data) self.hvsr_data = sprit_hvsr.generate_ppsds(params=self.hvsr_data, - ppsd_length=self.ppsd_length.get(), - overlap=self.overlap.get(), - period_step_octaves=self.perStepOct.get(), - remove_outliers=self.remove_outliers.get(), - outlier_std=self.outlier_std.get(), - skip_on_gaps=self.skip_on_gaps.get(), - db_bins=self.db_bins, - period_limits=self.period_limits, - period_smoothing_width_octaves=self.perSmoothWidthOct.get(), - special_handling=special_handling + remove_outliers=self.remove_outliers.get(), + outlier_std=self.outlier_std.get(), + + ppsd_length=self.ppsd_length.get(), + overlap=self.overlap.get(), + period_step_octaves=self.perStepOct.get(), + skip_on_gaps=self.skip_on_gaps.get(), + db_bins=self.db_bins, + period_limits=self.period_limits, + period_smoothing_width_octaves=self.perSmoothWidthOct.get(), + special_handling=special_handling, verbose=True ) + self.hvsr_results = sprit_hvsr.process_hvsr(params=self.hvsr_data, method=self.method_ind, smooth=self.hvsmooth_param, freq_smooth=self.freq_smooth.get(), f_smooth_width=self.fSmoothWidth.get(), - resample=self.hvresample_int, - remove_outlier_curves=self.outlierRembool.get(), + resample=self.hvresample_int, outlier_curve_std=self.outlierRemStDev.get()) self.hvsr_results = sprit_hvsr.check_peaks(hvsr_data=self.hvsr_results, hvsr_band = [self.hvsrBand_min.get(), self.hvsrBand_max.get()], - peak_water_level=self.peak_water_level) + peak_freq_range=[self.hvsrBand_min.get(), self.hvsrBand_max.get()]) + print(type(self.hvsr_results)) if isinstance(self.hvsr_results, sprit_hvsr.HVSRData): report_results(self.hvsr_results) #self.results_siteSelectFrame.grid_forget() @@ -6885,7 +7018,10 @@

Methods

if i==0: self.fig_noise, self.ax_noise, self.noise_windows_line_artists, self.noise_windows_window_artists = sprit_hvsr._get_removed_windows(input=hv_data, fig=self.fig_noise, ax=self.ax_noise, existing_xWindows=self.xWindows, time_type='matplotlib') self.fig_noise.canvas.draw() - + + if batch_data is None: + hvsr_data = hvsr_data['SITENAME'] + return hvsr_data self.fig_noise.canvas.draw() @@ -7994,6 +8130,7 @@

Methods

# RESULTS TAB self.results_tab = ttk.Frame(self.tab_control) + self.hvsr_results = {'site':''}#Just initialize for now # Create the Batch Site selection LabelFrame self.results_siteSelectFrame = ttk.LabelFrame(self.results_tab, text="HVSR Results") @@ -8005,9 +8142,13 @@

Methods

report_results(self.hvsr_results[sitename]) except: warnings.warn(f"Site {sitename} does not exist", UserWarning) - - self.site_options = [''] - self.selectedSite = tk.StringVar(value=self.site_options[0]) + + if isinstance(self.hvsr_results, sprit_hvsr.HVSRBatch): + sites = self.hvsr_results.sites + else: + sites = [self.hvsr_results['site']] + self.site_options = sites + self.selectedSite = tk.StringVar(value=sites[0]) self.site_dropdown = ttk.Combobox(self.results_siteSelectFrame, textvariable=self.selectedSite, values=self.site_options, validate='focusout', validatecommand=on_site_select) self.site_dropdown.config(width=30) self.results_siteSelectLabel.grid(row=0, column=0, columnspan=1, sticky='ew') diff --git a/docs/sprit_hvsr.html b/docs/sprit_hvsr.html index a5fab8f..7d15372 100644 --- a/docs/sprit_hvsr.html +++ b/docs/sprit_hvsr.html @@ -46,7 +46,7 @@

Module sprit.sprit_hvsr

import pickle import pkg_resources import tempfile -import textwrap +import traceback import warnings import xml.etree.ElementTree as ET import sys @@ -56,6 +56,7 @@

Module sprit.sprit_hvsr

import matplotlib.dates as mdates import matplotlib.pyplot as plt import numpy as np +import obspy from obspy.signal import PPSD import pandas as pd from pyproj import CRS, Transformer @@ -365,10 +366,17 @@

Module sprit.sprit_hvsr

gui_root.destroy() if sys.platform == 'linux': - 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.') + 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() - icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) - gui_root.iconbitmap(icon_path) + try: + icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon.png')) + gui_root.iconphoto(False, tk.PhotoImage(file=icon_path)) + #gui_root.iconbitmap(icon_path) + except Exception as e: + print(e) + print('icon not loaded') SPRIT_App(master=gui_root) #Open the app with a tk.Tk root gui_root.protocol("WM_DELETE_WINDOW", on_gui_closing) @@ -432,7 +440,7 @@

Module sprit.sprit_hvsr

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} @@ -496,7 +504,18 @@

Module sprit.sprit_hvsr

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: + except Exception as e: + if verbose: + 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} @@ -882,8 +901,8 @@

Module sprit.sprit_hvsr

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 = [] @@ -1090,6 +1109,38 @@

Module sprit.sprit_hvsr

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() @@ -1113,7 +1164,7 @@

Module sprit.sprit_hvsr

Parameters ---------- params : dict, HVSRData object, or HVSRBatch object - Dictionary containing all the parameters and other data of interest (stream and paz, for example) + 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 @@ -1257,15 +1308,15 @@

Module sprit.sprit_hvsr

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]), - int(np.where(EArr == cTime)[0]), - int(np.where(NArr == cTime)[0])]) + + 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: @@ -1330,9 +1381,9 @@

Module sprit.sprit_hvsr

hvsrDF['Use'] = True for gap in params['ppsds']['Z']['times_gaps']: - hvsrDF['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) hvsrDF.set_index('TimesProcessed', inplace=True) params['hvsr_df'] = hvsrDF @@ -2356,12 +2407,14 @@

Module sprit.sprit_hvsr

currTimesUsed={} hvsrDF = params['hvsr_df'] - - for k in ppsds: + 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 - input_ppsds = np.stack(currPPSDs) + used_ppsds = np.stack(currPPSDs) + #if reasmpling has been selected if resample is True or type(resample) is int: if resample is True: @@ -2507,10 +2560,14 @@

Module sprit.sprit_hvsr

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 - hvsr_out['hvsr_df'][bool_col] = ((avg_stdT - (std_stdT * outlier_curve_std)) < (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) & \ - ((avg_stdT + (std_stdT * outlier_curve_std)) > (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) + 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 = [] @@ -2544,7 +2601,6 @@

Module sprit.sprit_hvsr

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']) @@ -2731,10 +2787,10 @@

Module sprit.sprit_hvsr

if trEndTime < trStartTime and comp_end==comp_start: gap = [trEndTime,trStartTime] - - output['hvsr_df']['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + hvsrDF= output['hvsr_df'] + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) trEndTime = trace.stats.endtime @@ -3063,7 +3119,8 @@

Module sprit.sprit_hvsr

params = generate_ppsds(**generate_ppsds_kwargs) if generate_ppsds_kwargs['verbose']: print('\t{} successfully completed generate_ppsds()'.format(params['site'])) - except: + except Exception as e: + print(e) warnings.warn(f"Error in generate_ppsds({generate_ppsds_kwargs['params']['site']}, **generate_ppsds_kwargs)", RuntimeWarning) params = generate_ppsds_kwargs['params'] @@ -4016,8 +4073,9 @@

Module sprit.sprit_hvsr

if use_tkinter: try: - ax=self.ax_noise - fig=self.fig_noise + pass #Don't think this is being used anymore, defined in sprit_gui separately + #ax=ax_noise #self.ax_noise #? + #fig=fig_noise except: pass @@ -4262,7 +4320,7 @@

Module sprit.sprit_hvsr

if isinstance(input, (dict, HVSRData)): stream = input['stream'].copy() - elif isinstance(input, (obpsy.core.Trace.trace, obpsy,core.stream.Stream)): + elif isinstance(input, (obspy.core.Trace.trace, obspy.core.stream.Stream)): stream = input.copy() else: pass #Warning? @@ -4882,6 +4940,7 @@

Module sprit.sprit_hvsr

hvsr=hvsr_out['hvsr_curve'] + hvsrDF = hvsr_out['hvsr_df'] if hvsr_out['ind_hvsr_curves'].shape[0] > 0: #With arrays, original way of doing it hvsr_log_std = np.nanstd(np.log10(hvsr_out['ind_hvsr_curves']), axis=0) @@ -4891,8 +4950,9 @@

Module sprit.sprit_hvsr

logStackedata = np.log10(stackedData).tolist() for i, r in enumerate(logStackedata): logStackedata[i] = np.array(r) + hvsr_out['hvsr_df']['HV_Curves_Log10'] = logStackedata - hvsr_log_std = np.nanstd(np.stack(hvsr_out['hvsr_df']['HV_Curves_Log10'][hvsr_out['hvsr_df']['Use']]), axis=0) + hvsr_log_std = np.nanstd(np.stack(hvsr_out['hvsr_df']['HV_Curves_Log10'][hvsrDF['Use']]), axis=0) #The componenets are already calculated, don't need to recalculate aren't calculated at the time-step level hvsrp = np.add(hvsr_out['hvsr_curve'], hvsr_out['ind_hvsr_stdDev']) @@ -5944,13 +6004,15 @@

Module sprit.sprit_hvsr

point = list() for j in range(len(hvsrPeaks)): p = None - for k in range(len(hvsrPeaks[j])): + for k in range(len(hvsrPeaks.iloc[j])): if p is None: - p = hvsrPeaks[j][k] + p = hvsrPeaks.iloc[j][k] else: #Find closest peak in current time to (current) main hvsr peak - if abs(index - hvsrPeaks[j][k]) < abs(index - p): - p = hvsrPeaks[j][k] + if abs(index - hvsrPeaks.iloc[j][k]) < abs(index - p): + p = hvsrPeaks.iloc[j][k] + #p = hvsrPeaks[j][k] + #print(p=p1, p, p1) if p is not None: point.append(p) point.append(index) @@ -6620,8 +6682,8 @@

Parameters

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 = [] @@ -6828,6 +6890,38 @@

Parameters

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() @@ -6852,7 +6946,7 @@

Parameters

Parameters

params : dict, HVSRData object, or HVSRBatch object
-
Dictionary containing all the parameters and other data of interest (stream and paz, for example)
+
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
@@ -6884,7 +6978,7 @@

Returns

Parameters ---------- params : dict, HVSRData object, or HVSRBatch object - Dictionary containing all the parameters and other data of interest (stream and paz, for example) + 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 @@ -7028,15 +7122,15 @@

Returns

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]), - int(np.where(EArr == cTime)[0]), - int(np.where(NArr == cTime)[0])]) + + 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: @@ -7101,9 +7195,9 @@

Returns

hvsrDF['Use'] = True for gap in params['ppsds']['Z']['times_gaps']: - hvsrDF['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) hvsrDF.set_index('TimesProcessed', inplace=True) params['hvsr_df'] = hvsrDF @@ -7585,10 +7679,17 @@

Returns

gui_root.destroy() if sys.platform == 'linux': - 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.') + 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() - icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon_alpha.ico')) - gui_root.iconbitmap(icon_path) + try: + icon_path = pathlib.Path(pkg_resources.resource_filename(__name__, 'resources/icon/sprit_icon.png')) + gui_root.iconphoto(False, tk.PhotoImage(file=icon_path)) + #gui_root.iconbitmap(icon_path) + except Exception as e: + print(e) + print('icon not loaded') SPRIT_App(master=gui_root) #Open the app with a tk.Tk root gui_root.protocol("WM_DELETE_WINDOW", on_gui_closing) @@ -7639,7 +7740,7 @@

Returns

-def input_params(datapath, site='HVSR Site', network='AM', station='RAC84', loc='00', channels=['EHZ', 'EHN', 'EHE'], acq_date='2023-10-02', 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-03', 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

@@ -8463,12 +8564,14 @@

Returns

currTimesUsed={} hvsrDF = params['hvsr_df'] - - for k in ppsds: + 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 - input_ppsds = np.stack(currPPSDs) + used_ppsds = np.stack(currPPSDs) + #if reasmpling has been selected if resample is True or type(resample) is int: if resample is True: @@ -8614,10 +8717,14 @@

Returns

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 - hvsr_out['hvsr_df'][bool_col] = ((avg_stdT - (std_stdT * outlier_curve_std)) < (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) & \ - ((avg_stdT + (std_stdT * outlier_curve_std)) > (hvsr_out['hvsr_df'][hvsr_out['hvsr_df'][bool_col]][eval_col].apply(np.nanstd))) + 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 = [] @@ -8651,7 +8758,6 @@

Returns

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']) @@ -8887,10 +8993,10 @@

Returns

if trEndTime < trStartTime and comp_end==comp_start: gap = [trEndTime,trStartTime] - - output['hvsr_df']['Use'] = ((gap[0] < hvsrDF['TimesProcessed_Obspy']) & (gap[1] > hvsrDF['WindowEnd'])) | \ - ((gap[0] > hvsrDF['TimesProcessed_Obspy']) & (gap[0] < hvsrDF['WindowEnd'])) | \ - ((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['WindowEnd'])) + hvsrDF= output['hvsr_df'] + 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]))# | \ + #((gap[1] > hvsrDF['TimesProcessed_Obspy']) & (gap[1] < hvsrDF['TimesProcessed_ObspyEnd'])) trEndTime = trace.stats.endtime @@ -9113,7 +9219,7 @@

Raises

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} @@ -9177,7 +9283,18 @@

Raises

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: + except Exception as e: + if verbose: + 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} diff --git a/docs/sprit_utils.html b/docs/sprit_utils.html index 2b8a6ee..7ed2e8f 100644 --- a/docs/sprit_utils.html +++ b/docs/sprit_utils.html @@ -39,7 +39,7 @@

Module sprit.sprit_utils

try: # For distribution from sprit import sprit_hvsr except: #For testing - #import sprit_hvsr + import sprit_hvsr pass greek_chars = {'sigma': u'\u03C3', 'epsilon': u'\u03B5', 'teta': u'\u03B8'} diff --git a/pyproject.toml b/pyproject.toml index f100b00..6cf56f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "sprit" dynamic = ["readme"] license = {file = "LICENSE"} -version="0.1.37" +version="0.1.38" 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 e3e26a5..3ce1e40 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ name="sprit", author= "Riley Balikian", author_email = "balikian@illinois.edu", - version="0.1.37", + version="0.1.38", package_data={'sprit': ['resources/*', '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__/__init__.cpython-311.pyc b/sprit/__pycache__/__init__.cpython-311.pyc index 964eeddd1394412bea8b524fca32c9da60f5c5f3..2694d2d45a36d5f45a07d137d55caf1104ca996e 100644 GIT binary patch delta 20 acmZqRZQ$iz&dbZi00e)!Wj1n`vH<`uzXZzw delta 20 ZcmZqRZQ$iz&dbZi00ad=JR7-7*#Ig<1NHy_ diff --git a/sprit/__pycache__/sprit_cli.cpython-311.pyc b/sprit/__pycache__/sprit_cli.cpython-311.pyc index edbff3c7a0823605ae18e994713c5956b58df488..52cd1c29f5d5e3f192d341cc09ba70e42a86696a 100644 GIT binary patch delta 1126 zcmZuwO-vI(6rO3fWhu0@bP0co3lvM6EsGHl!JmWp8xu_-CMbp!cWJBbE}7keHZ^$g zfRPxaNC9h|HO(()gz=A18T{Mp)$$TAf4h!bn=%PiS0Igz`V7X>8 z_L5o?60PrMe^UGqACcoCPogpL27gw*5{iw4)DV9%szwr1{OI}M>9N463!_0^nITb? z-&nUeuqkET_+b4`1%;|+qg-()Z`A|a93i3Y1xDx%Jf(qAMRt$Sy3W1;FK>!|3=Kvp zd)leBSG%=ybp8CL3CP@Z-gF7=>b^fkU`jbF>&_yA7aP@sWeQiNLhb#VOCZuz?jz-V zjD(Jq3$SyI5xQqn;>N3tj&^W`$yJrCDf`rC6)Ih*x)) z3PV4=QRvSzd=JAdqfzAR-e7B|@q7VaB2^$N;L8QfB`*XMk`$G~Z1J{wNJ8rNv2$>j ztQry7X*m{?=ZtiSgcEU5QWds4p@?iCFe{QN8Q8Q;*tkqYHYx#)ht#Mn`G%6VvU+&a zEK0(r_1avB1j0(vbl6+K-lU0RlZ}4=%#0#T8mX|tv3`Gv6|nC$^0jR&+dHs@Qg6(N z+Iz&~JvvgRe z!?0Y4r|Wgvlc7CX+5;rl!am_1aVtHmJ$Y1B-Cu+|XBLj#Z^+d(uI*n|Rt8rG^}0@o zoRj(HZd|r34L=xu-l@C0Aigrq%cFV=2a!H*%;QD=meHAk3^R~r27o|(E9v}ti$C2D z0P#xInZ69umu32ZKos42Uj=o#H$(Sk>0Tg)`hhK3~EE zY?c~58JSfGVT`v%PsmXNI0G6Ca03+RLvdM1#Ka?H0+z;)rfAxb`_N#HYSXtPN71)N fwzjtNloPk+(GGY{VBC~PWq97CJ#lkpYqR+`v?~~R delta 468 zcmX@4b55OaIWI340}vRT6in?Fn8+u=m@-jaMVnojfsrASA&A&Mo1 z1xT`{vZb(QGlBFJ@h~x@vTm&V!s6uXY!wq)oLW>Ila!c~nVp%K7vqzkoS5U1Sdtjy zoS%|f9GqN~Sx{0O*kGYuUIDQ zbEpT4#sF=p6{r;~F$dWO0W|_Og3Ey7tHCY+i7_(th?THHrGZqI42+#3m&s7WyM(ci zk&z*VA(%l^ezPHO8l%uH#^@q;prT)lvA-B~Rx)VHZg%EZVw{{UAjfDvxl15};}%rc@qtBvQThV|oKUf5l=#2^C#o1H3ybM6Gl?<-0Oj~{H2?qr diff --git a/sprit/__pycache__/sprit_gui.cpython-311.pyc b/sprit/__pycache__/sprit_gui.cpython-311.pyc index b537a4dd0fa5d78d59978e9ee32d7f7dafddeabc..d57d7ef390944c1e0b9cd324aae0d4e8c4134a7c 100644 GIT binary patch delta 30 kcmZpf%hNKKhif@6FBbz4{ONAwYUN^Vm#k`e^