-
Notifications
You must be signed in to change notification settings - Fork 529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added publicID to station #3194
base: master
Are you sure you want to change the base?
Conversation
Alright @s-schneider, the CI is working again so the failures you see here are probably related to your changes. Take a look and see if you can figure out how to fix them. |
Hmm.. our inventory type classes are kept really close to the StationXML schema. Anything that diverges from it could potentially be trouble in the future, when we might have to adjust to changes in StationXML, or just be confusing to people because there are things that are not in StationXML or are missing when writing to StationXML. So, I'm not sure how I feel about this one.. It's quite a harmless looking change obviously, but it does have the above implications.. |
Would it be an option to keep this SCML specific piece of information in the |
Hm if we can add that field to the |
I think I would prefer that, and I don't see a big problem having it in |
Should be no problem, I’ll change that and push an update |
EB_response_NEW_stationXML.zip
vs
The code I used:
|
@s-schneider I've rebased this branch on current master and force pushed, to avoid merge conflicts. Can you continue work on this version? Or let me know if that's a problem for you. |
@@ -639,6 +640,8 @@ def select(self, network=None, station=None, location=None, channel=None, | |||
:param maxradius: Only include stations/channels within the specified | |||
maximum number of degrees from the geographic point defined by the | |||
latitude and longitude parameters. | |||
:type public_id: str, optional | |||
:param public_id: Only include stations matching with extra.public_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add to the docstring that this mainly is for data read from sc3ml files, so it's clear what this is about here
@@ -457,6 +458,8 @@ def select(self, station=None, location=None, channel=None, time=None, | |||
will be included in the result. This flag has no effect for | |||
initially empty stations which will always be retained if they | |||
are matched by the other parameters. | |||
:type public_id: str, optional | |||
:param public_id: Only include stations matching with extra.public_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
else: | ||
continue | ||
else: | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This confused me at first, although this might be doing what it's supposed to do, I would rewrite this, to make it less nested and less confusing.
Maybe something like..
if public_id is not None:
try:
sta_public_id = sta.extra.public_id
except AttributeError:
# deselect stations that do not have this attribute
continue
else:
if not fnmatch.fnmatch(sta_public_id.upper(), public_id.upper()):
continue
@@ -408,6 +408,9 @@ def test_inventory_select(self): | |||
assert sum_stations(inv.select(station="RJOB")) == 9 | |||
assert sum_stations(inv.select(station="R?O*")) == 9 | |||
|
|||
# Only Stations with public_id | |||
assert sum_stations(inv.select(public_id="TEST")) == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There needs to be a test added that is actually filtering out some stations but keeping a desired station. Right now only deselecting everything on arbitrary public_id="..."
input is checked.
@@ -179,6 +179,10 @@ def test_network_select(self): | |||
|
|||
# No matching station. | |||
assert sum(len(i) for i in net.select(station="RR")) == 0 | |||
|
|||
# Only stations with public_id | |||
assert sum(len(i) for i in net.select(public_id="TEST")) == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above, test needs improvement
obspy/io/seiscomp/inventory.py
Outdated
@@ -37,7 +38,8 @@ | |||
|
|||
SOFTWARE_MODULE = "ObsPy %s" % obspy.__version__ | |||
SOFTWARE_URI = "http://www.obspy.org" | |||
SCHEMA_VERSION = ['0.6', '0.7', '0.8', '0.9', '0.10', '0.11', '0.12'] | |||
SCHEMA_VERSION = "0.11" | |||
READABLE_VERSIONS = ['0.6', '0.7', '0.8', '0.9', '0.10', '0.11', '0.12'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change confused me at first, i didn't see any reason for it.. until i looked at individual commits. So this is a relic from some early commits adding WIP on writing sc3ml which later got partially reverted. Ideally these commits should be removed from history, they would just add confusion to the history, I think, considering they never were a working version but just unfinished WIP.
In any case, this change here needs to be reverted too. It's not needed for what this PR is intending.
@@ -92,7 +94,7 @@ def _read_sc3ml(path_or_file_object, **kwargs): | |||
root = etree.parse(path_or_file_object).getroot() | |||
|
|||
# Code can be used for version 0.6 to 0.12 (Seiscomp 4.x) | |||
for version in SCHEMA_VERSION: | |||
for version in READABLE_VERSIONS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
obspy/io/seiscomp/inventory.py
Outdated
'value': public_id, | ||
'namespace': ns | ||
} | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few things that should be changed here I think.
use namespaces correctly
Namespace should be set to the actual namespace value of the attribute publicID
that is being parsed and not quite arbitrarily "seiscmopml"
. There is an easy way that might be doing the right thing..
namespace = sta_element.nsmap[None]
... but this is working on assumptions how namespaces are set in sc3ml and might break later on.
So to correctly determine the namespace of this attribute, you should check the attribute for a namespace first and if it doesn't have one it should be OK to use the default namespace of it's element
match = re.match(r'{([^}]*)}.*', sta_element.tag)
if match:
namespace = match.group(1)
else:
namespace = sta_element.nsmap[None]
I haven't messed around with details of lxml and xml namespaces in a while, but it seems that the default namespace is set on the station element, even though the whole document is operating on the implicit default namespace declared on the root element, so it should be OK to assume we can use that.
Actually, as a last thought.. when accessing public_id = sta_element.get("publicID")
that is already assuming that publicID
has the default namespace of the station item, I believe, so maybe just using station default namespace is fine..
naming of extra item
I would probably keep the name publicID
as the name of the item in extra. Even though that means internally you would look at station.extra.publicID
which isn't in line with our Python object naming scheme.. this a) makes it clear that this is not coming from Python land and b) if writing an inventory read from sc3ml as stationxml, your custom attribute would kind of properly show up in the xml file as something like..
<FDSNStationXML xmlns="http://www.fdsn.org/xml/station/1" schemaVersion="1.2">
<Source>scxml import</Source>
<Sender>ObsPy Inventory</Sender>
<Module/>
<ModuleURI/>
<Created>2022-12-01T12:14:43.872676Z</Created>
<Network code="EB" startDate="1980-01-01T00:00:00.000000Z" restrictedStatus="open">
<Description>SINGLE STATION</Description>
<Station xmlns:ns0="seiscompml" code="EBR" startDate=..... ns0:public_id="Station/EB/EBR/2002-04-01T00:00:00.0000Z">
<Latitude unit="DEGREES">40.820599</Latitude>
<Longitude unit="DEGREES">0.4933</Longitude>
...
should set type as attribute
Then it would come out as an attribute on StationXML output as opposed to an element.
self.sc3ml_inventory.write(sc3ml_bytes, "STATIONXML") | ||
self.sc3ml_inventory.write( | ||
sc3ml_bytes, "STATIONXML", | ||
nsmap={'my_ns': 'seiscompml'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should use a proper sc3ml namespace URI
if hasattr(sta.extra, 'publicID'): | ||
if not fnmatch.fnmatch( | ||
sta.extra['publicID'].value.upper(), | ||
public_id.upper() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if publicID
in sc3ml is case sensitive, but personally, I'd probably leave the upper()
away. I know it's done like this in some other comparisons, and I'm not sure if I agree with that but it is what it is and thats more coming from the SEED perspective where everything was supposed to be all uppercase characters only anyway.
I pushed some of the adjustments, if you wanna work on the rest? |
CC @filefolder since you worked on sc3ml stuff recently |
sure, but still out digging holes for another week |
trying to wrap this up for the release @s-schneider @filefolder, maybe you can have a look, I think there was some last things to do There were some merge conflicts, so need to double-check, most notably 0.13 read support was added in the meantime, so that needs checking if that changes anything |
I think the example SCML probably needs to be rinsed through to a newer version, plus you can't specify file storage type (eg Steim2) anymore I think. While I'm pretty sure reading in event data works fine for 0.13, I never really tested reading inventory files. Currently seeing "0.13 not supported" errors in 1.4.1 but it's a but too late for me to investigate. Attached is an example in the meantime |
What does this PR do?
Adds public_id to station objects, if station is read from inventory files from seiscomp.
Why was it initiated? Any relevant Issues?
see #3193
PR Checklist
master
for new features,maintenance_...
for bug fixesJust add the "build_docs" tag to this PR.
Docs will be served at docs.obspy.org/pr/{branch_name} (do not use master branch).
Please post a link to the relevant piece of documentation.
clients.fdsn
) should be tested for the PR,just add the "test_network" tag to this PR.
CHANGELOG.txt
.CONTRIBUTORS.txt
.from all the CI builds look correct. Add the "upload_plots" tag so that plotting
outputs are attached as artifacts.