From de07b2786bb94122b19c64061448b611e8fd0a99 Mon Sep 17 00:00:00 2001 From: Evan Goetz Date: Thu, 5 Dec 2024 11:02:33 -0800 Subject: [PATCH 1/3] Update segments module to handle incoming changes from gwpy DataQualityDict updates --- gwsumm/segments.py | 52 +++++++++++++++++++------------------------- gwsumm/state/core.py | 9 +++++--- pyproject.toml | 9 ++++---- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/gwsumm/segments.py b/gwsumm/segments.py index b9f66aa1..e50c6d7f 100644 --- a/gwsumm/segments.py +++ b/gwsumm/segments.py @@ -45,18 +45,12 @@ ) __author__ = 'Duncan Macleod ' - -SEGDB_URLS = [ - 'https://segdb.ligo.caltech.edu', - 'https://metaserver.phy.syr.edu', - 'https://geosegdb.atlas.aei.uni-hannover.de', - 'http://10.20.50.30' # geosegdb internal -] +__credits__ = 'Evan Goetz ' def get_segments(flag, validity=None, config=ConfigParser(), cache=None, query=True, return_=True, coalesce=True, padding=None, - ignore_undefined=False, segdb_error='raise', url=None, + ignore_undefined=False, segdb_error='raise', host=None, **read_kw): """Retrieve the segments for a given flag @@ -83,8 +77,8 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, - ``gps-start-time``, and ``gps-end-time``, if ``validity`` is not given - - ``url`` (the remote hostname for the segment database) if - the ``url`` keyword is not given + - ``host`` (the remote hostname for the segment database) if + the ``host`` keyword is not given cache : :class:`glue.lal.Cache`, optional a cache of files from which to read segments, otherwise segments @@ -111,7 +105,7 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, segments - ``'ignore'`` : silently ignore the error and return no segments - url : `str`, optional + host : `str`, optional the remote hostname for the target segment database return_ : `bool`, optional, default: `True` @@ -211,9 +205,9 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, new[f].active &= newsegs if coalesce: new[f].coalesce() - vprint(" Read %d segments for %s (%.2f%% coverage).\n" - % (len(new[f].active), f, - float(abs(new[f].known))/float(abs(newsegs))*100)) + cov = float(abs(new[f].known))/float(abs(newsegs))*100 + vprint(f" Read {len(new[f].active)} segments for " + f"{f} ({cov:.2f}%% coverage).\n") else: if len(newsegs) >= 10: qsegs = span @@ -221,30 +215,28 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, qsegs = newsegs # parse configuration for query kwargs = {} - if url is not None: - kwargs['url'] = url + if host is not None: + kwargs['host'] = host else: try: - kwargs['url'] = config.get('segment-database', 'url') + kwargs['host'] = config.get('segment-database', 'host') except (NoSectionError, NoOptionError): pass - if kwargs.get('url', None) in SEGDB_URLS: - query_func = DataQualityDict.query_segdb - else: - query_func = DataQualityDict.query_dqsegdb try: - new = query_func(allflags, qsegs, on_error=segdb_error, - **kwargs) + new = DataQualityDict.query_dqsegdb( + allflags, + qsegs, + on_error=segdb_error, + **kwargs) except Exception as e: # ignore error from SegDB if segdb_error in ['ignore', None]: pass # convert to warning elif segdb_error in ['warn']: - print('%sWARNING: %sCaught %s: %s [gwsumm.segments]' - % (WARNC, ENDC, type(e).__name__, str(e)), - file=sys.stderr) - warnings.warn('%s: %s' % (type(e).__name__, str(e))) + print(f"{WARNC}WARNING: {ENDC}Caught {type(e).__name__}: " + f"{str(e)} [gwsumm.segments]", file=sys.stderr) + warnings.warn(f"{type(e).__name__}: {str(e)}") # otherwise raise as normal else: raise @@ -254,9 +246,9 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, new[f].active &= newsegs if coalesce: new[f].coalesce() - vprint(" Downloaded %d segments for %s (%.2f%% coverage).\n" - % (len(new[f].active), f, - float(abs(new[f].known))/float(abs(newsegs))*100)) + cov = float(abs(new[f].known))/float(abs(newsegs))*100 + vprint(f" Downloaded {len(new[f].active)} segments for " + f"{f} ({cov:.2f}%% coverage).\n") # record new segments globalv.SEGMENTS += new for f in new: diff --git a/gwsumm/state/core.py b/gwsumm/state/core.py index f5c64310..b660714b 100644 --- a/gwsumm/state/core.py +++ b/gwsumm/state/core.py @@ -64,14 +64,17 @@ class SummaryState(DataQualityFlag): logical combination of flags that define known and active segments for this state (see :attr:`documentation ` for details) + hours : optional key : `str`, optional registry key for this state, defaults to :attr:`~SummaryState.name` + filename : `str`, optional + host : `str`, optional """ MATH_DEFINITION = re.compile(r'(%s)' % '|'.join(MATHOPS.keys())) def __init__(self, name, known=SegmentList(), active=SegmentList(), description=None, definition=None, hours=None, key=None, - filename=None, url=None): + filename=None, host=None): """Initialise a new `SummaryState` """ # allow users to specify known as (start, end) @@ -88,7 +91,7 @@ def __init__(self, name, known=SegmentList(), active=SegmentList(), self.definition = None self.key = key self.hours = hours - self.url = url + self.host = host if known and active: self.ready = True else: @@ -244,7 +247,7 @@ def from_ini(cls, config, section): return cls(name, known=[(start, end)], hours=hours, **params) def _fetch_segments(self, config=GWSummConfigParser(), **kwargs): - kwargs.setdefault('url', self.url) + kwargs.setdefault('host', self.host) segs = get_segments([self.definition], self.known, config=config, **kwargs)[self.definition].round(contract=True) self.known = segs.known diff --git a/pyproject.toml b/pyproject.toml index cd294137..f51c4e8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,10 +36,11 @@ classifiers = [ ] dependencies = [ - "astropy >=3.0.0", + "astropy >=5.0.0", + "dqsegdb2 >=1.2.0", "gwdatafind >=1.1.1", "gwdetchar >=2.3.2", - "gwpy >=3.0.9", + "gwpy >=4.0.0", "gwtrigfind", "lalsuite", "lscsoft-glue >=1.60.0", @@ -47,11 +48,11 @@ dependencies = [ "markdown", "MarkupPy", "matplotlib >=3.5", - "numpy >=1.16", + "numpy >=1.19.5", "pygments >=2.7.0", "python-dateutil", "igwn-ligolw", - "scipy >=1.2.0", + "scipy >=1.6.0", ] dynamic = ["version"] From 58f642bc1f653af8eac9904d4f0ddb2c4999b87e Mon Sep 17 00:00:00 2001 From: Evan Goetz Date: Thu, 14 May 2026 13:15:31 -0700 Subject: [PATCH 2/3] Update supported python versions --- .github/workflows/build.yml | 3 ++- docs/environment.yml | 9 +++++---- pyproject.toml | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f1e8c9a..a5ff7e37 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,8 +37,9 @@ jobs: - macOS - Ubuntu python-version: - - "3.10" - "3.11" + - "3.12" + - "3.13" runs-on: ${{ matrix.os }}-latest # this is needed for conda environments to activate automatically diff --git a/docs/environment.yml b/docs/environment.yml index f585572a..3f24a1aa 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -8,10 +8,11 @@ dependencies: - setuptools-scm - wheel # install - - astropy >=3.0.0 + - astropy >=5.0.0 + - dqsegdb2 >=1.2.0 - gwdatafind >=1.1.1 - gwdetchar >=2.3.2 - - gwpy >=3.0.9 + - gwpy >=4.0.0 - gwtrigfind - lalsuite - lscsoft-glue >=1.60.0 @@ -19,11 +20,11 @@ dependencies: - markdown - MarkupPy - matplotlib >=3.5 - - numpy >=1.16 + - numpy >=1.19.5 - pygments >=2.7.0 - python-dateutil - igwn-ligolw - - scipy >=1.2.0 + - scipy >=1.6.0 # docs - numpydoc - sphinx diff --git a/pyproject.toml b/pyproject.toml index f51c4e8f..2d7380c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,8 +28,9 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Astronomy", "Topic :: Scientific/Engineering :: Physics", From c3b0eaafa6b0cacb0038cd5772fedd7cbe7d1456 Mon Sep 17 00:00:00 2001 From: Evan Goetz Date: Thu, 14 May 2026 15:57:13 -0700 Subject: [PATCH 3/3] Improve code for segment database query --- gwsumm/segments.py | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/gwsumm/segments.py b/gwsumm/segments.py index e50c6d7f..68be98aa 100644 --- a/gwsumm/segments.py +++ b/gwsumm/segments.py @@ -20,9 +20,7 @@ """Utilities for segment handling and display """ -import sys import operator -import warnings from collections import OrderedDict from configparser import ( DEFAULTSECT, @@ -40,8 +38,6 @@ from .utils import ( re_flagdiv, vprint, - WARNC, - ENDC, ) __author__ = 'Duncan Macleod ' @@ -214,33 +210,18 @@ def get_segments(flag, validity=None, config=ConfigParser(), cache=None, else: qsegs = newsegs # parse configuration for query - kwargs = {} - if host is not None: - kwargs['host'] = host - else: - try: - kwargs['host'] = config.get('segment-database', 'host') - except (NoSectionError, NoOptionError): - pass try: - new = DataQualityDict.query_dqsegdb( - allflags, - qsegs, - on_error=segdb_error, - **kwargs) - except Exception as e: - # ignore error from SegDB - if segdb_error in ['ignore', None]: - pass - # convert to warning - elif segdb_error in ['warn']: - print(f"{WARNC}WARNING: {ENDC}Caught {type(e).__name__}: " - f"{str(e)} [gwsumm.segments]", file=sys.stderr) - warnings.warn(f"{type(e).__name__}: {str(e)}") - # otherwise raise as normal - else: - raise - new = DataQualityDict() + host = config.get('segment-database', 'host') + except (NoSectionError, NoOptionError): + host = None + segdb_error = segdb_error or 'ignore' # if None, set to 'ignore' + # query segment database + new = DataQualityDict.query_dqsegdb( + allflags, + qsegs, + on_error=segdb_error, + host=host, + ) for f in new: new[f].known &= newsegs new[f].active &= newsegs