From 170680f842c335b590cd2d3d37065aea85f80280 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Wed, 5 Mar 2025 11:36:39 -0700
Subject: [PATCH 1/7] modify obspy code to get Q8's response

---
 nexus/obspyImproved.py | 178 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 176 insertions(+), 2 deletions(-)

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index f1c6bd62..802180d9 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -6,9 +6,13 @@ Lloyd Carothers
 """
 from collections import defaultdict
 import os
+import io
+from urllib.parse import urlparse
 
+import obspy
 from obspy import read as obspy_read
 from obspy import Inventory
+from obspy.clients.nrl.client import NRLPath, NRL, RemoteNRL, LocalNRL
 from obspy import UTCDateTime
 from obspy.core.inventory import (Network, Station, Channel,
                                   Site, Equipment)
@@ -20,6 +24,8 @@ from . import hardware
 
 MODULE = 'Nexus.2023.4.0.0'
 MODULE_URI = 'www.passcal.nmt.edu'
+NRL_URL = 'http://ds.iris.edu/NRL'
+NRL_ROOT = NRL_URL
 
 class InventoryIm(Inventory):
     '''
@@ -423,8 +429,7 @@ class InventoryIm(Inventory):
                 sr = '{:g}'.format(chan.sample_rate)
                 dl_keys = dl.get_nrl_keys(gain, sr)
                 try:
-                    response = hardware.get_nrl_response(dl_keys,
-                                                         sensor_keys)
+                    response = get_nrl_response(dl_keys, sensor_keys)
                     chan.response = response
                     print('Response computed.')
                 except Exception as e:
@@ -739,8 +744,177 @@ def scan_ms(dir_name, status_message=print):
     print(f'Scan took: {time.time() - start}')
     return streams, mseed_files
 
+
 def quick_scan_ms(dir_name, status_message=print):
     import time
     start = time.time()
 
     print(f'Scan took: {time.time() - start}')
+
+
+class NRLIm(NRL):
+    """
+    Improve NRL object to create instance of RemoteNRLIm and LocalNRLIm
+    """
+    def __new__(cls, root=None):
+        # root provided and it's no web URL
+        if root:
+            scheme = urlparse(root).scheme
+            if scheme in ('http', 'https'):
+                instance = object.__new__(RemoteNRLIm)
+            else:
+                # Check if it's really a folder on the file-system.
+                if not os.path.isdir(root):
+                    msg = ("Provided path '{}' seems to be a local file path "
+                           "but the directory does not exist.").format(root)
+                    raise ValueError(msg)
+                instance = object.__new__(LocalNRLIm)
+        else:
+            # Otherwise delegate to the remote NRL client to deal with all kinds
+            # of remote resources (currently only HTTP).
+            instance = object.__new__(RemoteNRLIm)
+        instance.root = root
+        NRL.__init__(instance)
+
+        return instance
+
+
+class RemoteNRLIm(RemoteNRL):
+    """
+    Improve RemoteNRLIm to use new _get_response()
+    """
+    def _get_response(self, base, keys):
+        """
+        Improve _get_response to use _get_value() function instead of
+        NRLDict's __getitem__()
+
+        Internal helper method to fetch a response
+
+        This circumvents the warning message that is shown for NRL v2 when a
+        datalogger-only response is fetched
+
+        :type base: str
+        :param base: either "sensors" or "dataloggers"
+        :type keys: list of str
+        :param keys: list of lookup keys
+        """
+        node = getattr(self, base)
+        for key in keys:
+            node = _get_value(node, key)
+
+        # Parse to an inventory object and return a response object.
+        description, path, resp_type = node
+        with io.BytesIO(self._read_resp(path).encode()) as buf:
+            buf.seek(0, 0)
+            return obspy.read_inventory(
+                buf, format=resp_type)[0][0][0].response, resp_type
+
+
+class LocalNRLIm(LocalNRL):
+    """
+    Improve LocalNRLIm to use new _get_response()
+    """
+    def _get_response(self, base, keys):
+        """
+        Improve _get_response to use _get_value() function instead of
+        NRLDict's __getitem__()
+
+        Internal helper method to fetch a response
+
+        This circumvents the warning message that is shown for NRL v2 when a
+        datalogger-only response is fetched
+
+        :type base: str
+        :param base: either "sensors" or "dataloggers"
+        :type keys: list of str
+        :param keys: list of lookup keys
+        """
+        node = getattr(self, base)
+        for key in keys:
+            node = _get_value(node, key)
+
+        # Parse to an inventory object and return a response object.
+        description, path, resp_type = node
+        with io.BytesIO(self._read_resp(path).encode()) as buf:
+            buf.seek(0, 0)
+            return obspy.read_inventory(
+                buf, format=resp_type)[0][0][0].response, resp_type
+
+
+def get_nrl_response(dl_keys, sensor_keys):
+    """
+    improve hardware.py's get_nrl_response()
+    """
+    nrl = NRLIm(NRL_ROOT)
+    return nrl.get_response(dl_keys, sensor_keys)
+
+
+def _get_path(nrl_dict, key, compared_value, op):
+    """
+    In case the key start with comparison operator "<=" or ">",
+    compare the given compared_value with the value in the key
+    and return the corresponding NRLPath.
+
+    :param nrl_dict: an NRLDict instance
+    :param key: key with comparison operator. Ex "<= 200 sps"
+    :param compared_value: the value to be compared
+    :param op: operator to be checked. Ex: "<=" or ">"
+    """
+    comparison_ops = {
+        '<=': lambda x, y: x <= y,
+        '>': lambda x, y: x > y
+    }
+    org_key = key
+    if key.strip().startswith(op):
+        upper_limit_str = \
+            key.replace(op, '').replace('sps', '').strip()
+        upper_limit = float(upper_limit_str)
+        if comparison_ops[op](compared_value, upper_limit):
+            return nrl_dict.__getitem__(org_key)
+
+
+def _get_value(nrl_dict, name):
+    """
+    Improve from obspy.client.nrl.client.NRLDict's __getitem__
+    This function along with NRLIm, RemoteNRLIm, LocalNRLIm, get_nrl_response,
+    _get_path should be removed and replace get_nrl_response with
+    hardware.get_nrl_response when obspy release an update for getting response
+    for Q8.
+
+    Getting path from nrl_dict by using name as key
+    Normally name will be one of the keys of the nrl_dict.
+    """
+    try:
+        value = nrl_dict.__getitem__(name)
+    except KeyError as e:
+        """
+        The improvement is for the case of Q8 when name won't be one of
+        the key of the nrl_dict anymore. The NRL documentation provides
+        question "Is the highest simultaneous sampling rate recorded" with
+        different keys that are comparison expression strings with a standard
+        value, e.g. "<= 200 sps", typically the maximum or minimum sample rate.
+        This ensures that the downsampling of the sample rate aligns with the
+        specified value. In such cases, the program must apply the comparison
+        using the given key to determine the correct path.
+        """
+        try:
+            name_float = float(name)
+            value = None
+            keys = nrl_dict.keys()
+            for key in keys:
+                value = _get_path(nrl_dict, key, name_float, "<=")
+                if value is not None:
+                    break
+                value = _get_path(nrl_dict, key, name_float, ">")
+                if value is not None:
+                    break
+            if value is None:
+                raise e
+        except ValueError:
+            raise e
+
+    # if encountering a not yet parsed NRL Path, expand it now
+    if isinstance(value, NRLPath):
+        value = nrl_dict._nrl._parse_ini(value)
+        nrl_dict[name] = value
+    return value
-- 
GitLab


From c7657ad4690e8175b69c7349ab62a5f2859ade47 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Wed, 5 Mar 2025 13:54:08 -0700
Subject: [PATCH 2/7] change variable name to be more descriptive

---
 nexus/obspyImproved.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index 802180d9..c1f64b6c 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -866,10 +866,10 @@ def _get_path(nrl_dict, key, compared_value, op):
     }
     org_key = key
     if key.strip().startswith(op):
-        upper_limit_str = \
+        standard_value_str = \
             key.replace(op, '').replace('sps', '').strip()
-        upper_limit = float(upper_limit_str)
-        if comparison_ops[op](compared_value, upper_limit):
+        standard_value = float(standard_value_str)
+        if comparison_ops[op](compared_value, standard_value):
             return nrl_dict.__getitem__(org_key)
 
 
-- 
GitLab


From 9c0bafa0cac510ef67513c8d21563b25a27a2b37 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Thu, 6 Mar 2025 08:31:49 -0700
Subject: [PATCH 3/7] import NRL_URL instead defining one

---
 nexus/etc/nexus.hardware | Bin 0 -> 4616 bytes
 nexus/obspyImproved.py   |  12 ++++++------
 2 files changed, 6 insertions(+), 6 deletions(-)
 create mode 100644 nexus/etc/nexus.hardware

diff --git a/nexus/etc/nexus.hardware b/nexus/etc/nexus.hardware
new file mode 100644
index 0000000000000000000000000000000000000000..38845bf36bbfd9b417def3b2fb71d97432047769
GIT binary patch
literal 4616
zcmd5=%WoS+7<W?VUD~81^p#Wt1(b-`Svv`B#G`Q?$Bpc4;zt69R;!IY_Ds6ob@!3t
zN|lO4D}+Yk(CLBp!Wj;L;KCmOC(az;%$Z)f@y*)a?7Fo|38l5<*UWss`R4cizHess
zR`}jzZ^(VIBRc-bv7$sZ%hy#Cb2cEG+6pb%{4Sr#^XVB9V*LfITZSoGKIS+1Gz;r$
z4Tkp0DrbXoKC4{C4U5mPfg1|76sOKVb#|s%f7&rst<G70ay=cHFLE{#i%S-YphfA@
z4bH-`MM>f|Cw)y=GDuz`!(^0<fH@nHRo$pz+oUB6EQ==9H0spQg2eCmO~%1w!Zn#@
z;{|M%ur{}@npe@LX_TFk4aR-hNIbs6+0f#`ISFl$8ng|^C3rRe_+4OOF_;7BWD9hp
zV4Jvf6;liAfK@0KBG7-7O~zm)RJUwZ({LF{vAHD)*#?r9=9U%$%VNW>5vpQ6CXmlI
zkqIKN3Y>TlN0_@f3v)~7y5YDUP6u$#%m;CVxxlHL7(BPTA<YYqA}*416M|wl>KOR7
zcA~e!_kKP46fzlJQEfGARIB(ONM*<}hytF~El`wD%RoN0ii)WWXQTNdip@*tP4O8i
ztS2~VaAZ?cOZbwZm0k2q&uyOPWHi$&z5@a5&le+LD3%4f5OO_~-AHpbW$ak>Mzmy@
zI7;<Bpu{j6QQ?B2TcGB_eEX-T^AYGZ9FUYk%Uou!h-jNm4NMiF)S@=sqjm#&CVV}0
zLu-I?sj5N8(KfyUI;modUxCH4-tBcxrdp~;GRWXGn^^O}MY^@IJzx6vRL#LWePJO)
z!oM7Uz=kR&zUE-P)Zpo6ltMrg)$5L}I64)=@7d<;xUWSiW2<D+x=jrs<!wU~qYfL6
z?KA36ZfwcL0%s@u?LpHcE3`^M_$X;Oy1<z5oKZ|wuVS%W(*^=w?(D$2pmMUaxxAz7
zsU}rj*JNjhye5;gS2z$el{9drLQ52Aw~C<7cAN@=(fy)yN-0$o8)mmE*i<TxUJ_V}
zt7kT_vX)*eCbE$DiVhJpRfs+WgB^y2iD>EVh6y)N5MP&DEJp8u<T5=ZO6EwM%oB;k
z$O2g;NM?t90*S-2hMUG!mFm7ojqkTA-n#dLMh0az;*Si_Q^qA)bIDMe@w3!gUBf`G
z4N^V%SSdR;)u70&da}3+KK%HFc-_Cvo0WS^Gp++WKn^x-@X}T9m{YGm(s-<fRm(B4
zt9Gcv#DKVgcE^0KRn(H8G1C)hH7XSg+dLCuqrS0atf>voPWxOJ4oBVpZj?YqQ>&Vx
z+8<DxY<V71Y$f#a7AP8G?J2#rAhIcwoJ{gE>vKi#x;WvR7SbK6x2r1hVOMK%8J6bk
zsPG|b(NNA&bsL)|>~H<K`FW`TwdNQZXJgqlIhDwxL=h#jSyb381Zz)N3>KBA+^Rf@
zWQvnB<P<r>4s9e?;Wtzx(H6-5nN}&7O(&wC+!D!5BA%}#%6bZ%NHU4TPTI^(SATEI
z<eW^-`;z6I7S8+R0$GOSxd`tSSGjdi?lpnY6fQ~0WOaYC^!{XnGPxv^HIhwVcqkkR
zg*usr+$;cQF%u$NPok7udC~}%biqlkD<^G7f}9L&rt-;@Ts$Z<w}F{Eoy>SsK7VGm
zlN()`Sw8jE*PmVf<A)$KQ1#s!bpW~C2T~sR3SCn#Fx~gnFaH`Mk7p%VYP`&RCVJUU
z!Kt824lRGa><YJo6)=$4K%xev4))=LB-1y*&Ue7hw}EW(rhO6EN&XvlU_l4a%um3|
z&o4GBo84J?R+;o0u=4v0ok^LsuB>=vFt8g9BvaYK+SY;hq(6b0hfi5~|JNF`d9f=q
z%dfj7remM}kM^Y9a1WdS;=6s~t7FghCVt*khP=_W{yvtQgYQbaCz`aJbZPMp;jO)?
zJ?Zo2<&gtqZ|*!N<E`T()v;<K)kg5p0Ex?Q;Od&oou5VG@_=HqC<c!wV8kpUv`VmL
xBXRae@4koN$wjk6Yob-C24__ZRSZBDu<ljC9S-~4@a|iJFSrQ9;Wl`|{~Ogm{D%Ml

literal 0
HcmV?d00001

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index c1f64b6c..695c211c 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -21,11 +21,11 @@ from obspy.io.mseed.core import _is_mseed
 from obspy.io.mseed import util
 
 from . import hardware
+from .hardware import NRL_ROOT
+
 
 MODULE = 'Nexus.2023.4.0.0'
 MODULE_URI = 'www.passcal.nmt.edu'
-NRL_URL = 'http://ds.iris.edu/NRL'
-NRL_ROOT = NRL_URL
 
 class InventoryIm(Inventory):
     '''
@@ -889,10 +889,10 @@ def _get_value(nrl_dict, name):
     except KeyError as e:
         """
         The improvement is for the case of Q8 when name won't be one of
-        the key of the nrl_dict anymore. The NRL documentation provides
-        question "Is the highest simultaneous sampling rate recorded" with
-        different keys that are comparison expression strings with a standard
-        value, e.g. "<= 200 sps", typically the maximum or minimum sample rate.
+        nrl_dict's keys anymore. The NRL documentation provides question
+        "Is the highest simultaneous sampling rate recorded" with different
+        keys that are comparison expression strings with a standard value,
+        e.g. "<= 200 sps", typically the maximum or minimum sample rate.
         This ensures that the downsampling of the sample rate aligns with the
         specified value. In such cases, the program must apply the comparison
         using the given key to determine the correct path.
-- 
GitLab


From fec60cc2a615018701ce3aecd344a2233b172c22 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Thu, 6 Mar 2025 08:34:06 -0700
Subject: [PATCH 4/7] Revert "import NRL_URL instead defining one"

This reverts commit 9c0bafa0cac510ef67513c8d21563b25a27a2b37.
---
 nexus/etc/nexus.hardware | Bin 4616 -> 0 bytes
 nexus/obspyImproved.py   |  12 ++++++------
 2 files changed, 6 insertions(+), 6 deletions(-)
 delete mode 100644 nexus/etc/nexus.hardware

diff --git a/nexus/etc/nexus.hardware b/nexus/etc/nexus.hardware
deleted file mode 100644
index 38845bf36bbfd9b417def3b2fb71d97432047769..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4616
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

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index 695c211c..c1f64b6c 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -21,11 +21,11 @@ from obspy.io.mseed.core import _is_mseed
 from obspy.io.mseed import util
 
 from . import hardware
-from .hardware import NRL_ROOT
-
 
 MODULE = 'Nexus.2023.4.0.0'
 MODULE_URI = 'www.passcal.nmt.edu'
+NRL_URL = 'http://ds.iris.edu/NRL'
+NRL_ROOT = NRL_URL
 
 class InventoryIm(Inventory):
     '''
@@ -889,10 +889,10 @@ def _get_value(nrl_dict, name):
     except KeyError as e:
         """
         The improvement is for the case of Q8 when name won't be one of
-        nrl_dict's keys anymore. The NRL documentation provides question
-        "Is the highest simultaneous sampling rate recorded" with different
-        keys that are comparison expression strings with a standard value,
-        e.g. "<= 200 sps", typically the maximum or minimum sample rate.
+        the key of the nrl_dict anymore. The NRL documentation provides
+        question "Is the highest simultaneous sampling rate recorded" with
+        different keys that are comparison expression strings with a standard
+        value, e.g. "<= 200 sps", typically the maximum or minimum sample rate.
         This ensures that the downsampling of the sample rate aligns with the
         specified value. In such cases, the program must apply the comparison
         using the given key to determine the correct path.
-- 
GitLab


From 684fec5f7ac0208f6cbd994d91d28fb38f1bab97 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Thu, 6 Mar 2025 08:35:49 -0700
Subject: [PATCH 5/7] import NRL_URL instead defining one

---
 nexus/obspyImproved.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index c1f64b6c..7c309897 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -21,11 +21,10 @@ from obspy.io.mseed.core import _is_mseed
 from obspy.io.mseed import util
 
 from . import hardware
+from .hardware import NRL_ROOT
 
 MODULE = 'Nexus.2023.4.0.0'
 MODULE_URI = 'www.passcal.nmt.edu'
-NRL_URL = 'http://ds.iris.edu/NRL'
-NRL_ROOT = NRL_URL
 
 class InventoryIm(Inventory):
     '''
-- 
GitLab


From c4f40b665baf17c04c31e9537cd382ad5b9e25c1 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Wed, 12 Mar 2025 11:26:05 -0600
Subject: [PATCH 6/7] use built-in functions from operator instead of using
 lambdas

---
 nexus/obspyImproved.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index 7c309897..e32e0b2c 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -8,6 +8,7 @@ from collections import defaultdict
 import os
 import io
 from urllib.parse import urlparse
+import operator
 
 import obspy
 from obspy import read as obspy_read
@@ -852,16 +853,17 @@ def _get_path(nrl_dict, key, compared_value, op):
     """
     In case the key start with comparison operator "<=" or ">",
     compare the given compared_value with the value in the key
-    and return the corresponding NRLPath.
+    and return the corresponding value of the key which isNRLPath.
 
     :param nrl_dict: an NRLDict instance
     :param key: key with comparison operator. Ex "<= 200 sps"
     :param compared_value: the value to be compared
     :param op: operator to be checked. Ex: "<=" or ">"
+    :return  an NRLPath
     """
     comparison_ops = {
-        '<=': lambda x, y: x <= y,
-        '>': lambda x, y: x > y
+        '<=': operator.le,
+        '>': operator.gt
     }
     org_key = key
     if key.strip().startswith(op):
-- 
GitLab


From 4a422387d61e74e2b2bd51cacc7ac46b0bd6e145 Mon Sep 17 00:00:00 2001
From: ldam <ldam@passcal.nmt.edu>
Date: Thu, 13 Mar 2025 14:06:28 -0600
Subject: [PATCH 7/7] use super instead of hard coding class to show the
 hierarchy of inheritance

---
 nexus/obspyImproved.py | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/nexus/obspyImproved.py b/nexus/obspyImproved.py
index e32e0b2c..fa136b5e 100644
--- a/nexus/obspyImproved.py
+++ b/nexus/obspyImproved.py
@@ -761,20 +761,20 @@ class NRLIm(NRL):
         if root:
             scheme = urlparse(root).scheme
             if scheme in ('http', 'https'):
-                instance = object.__new__(RemoteNRLIm)
+                instance = super(NRL, cls).__new__(RemoteNRLIm)
             else:
                 # Check if it's really a folder on the file-system.
                 if not os.path.isdir(root):
                     msg = ("Provided path '{}' seems to be a local file path "
                            "but the directory does not exist.").format(root)
                     raise ValueError(msg)
-                instance = object.__new__(LocalNRLIm)
+                instance = super(NRL, cls).__new__(LocalNRLIm)
         else:
-            # Otherwise delegate to the remote NRL client to deal with all kinds
-            # of remote resources (currently only HTTP).
-            instance = object.__new__(RemoteNRLIm)
+            # Otherwise delegate to the remote NRL client to deal with all
+            # kinds of remote resources (currently only HTTP).
+            instance = super(NRL, cls).__new__(RemoteNRLIm)
         instance.root = root
-        NRL.__init__(instance)
+        cls.__init__(instance)
 
         return instance
 
@@ -849,7 +849,7 @@ def get_nrl_response(dl_keys, sensor_keys):
     return nrl.get_response(dl_keys, sensor_keys)
 
 
-def _get_path(nrl_dict, key, compared_value, op):
+def _get_nrl_path_from_comparison_key(nrl_dict, key, compared_value, op):
     """
     In case the key start with comparison operator "<=" or ">",
     compare the given compared_value with the value in the key
@@ -903,10 +903,12 @@ def _get_value(nrl_dict, name):
             value = None
             keys = nrl_dict.keys()
             for key in keys:
-                value = _get_path(nrl_dict, key, name_float, "<=")
+                value = _get_nrl_path_from_comparison_key(
+                    nrl_dict, key, name_float, "<=")
                 if value is not None:
                     break
-                value = _get_path(nrl_dict, key, name_float, ">")
+                value = _get_nrl_path_from_comparison_key(
+                    nrl_dict, key, name_float, ">")
                 if value is not None:
                     break
             if value is None:
-- 
GitLab