14.2. Provenance and Bibliography#

ProvenanceMeta records how a transfer-function document came to be – creation time, creating application, creator, and submitter – so that history survives a format conversion instead of being reset every time a file is re-saved. Reference, CopyrightInfo, Person, and Software supply the bibliographic detail that a provenance or copyright record is built from: who to cite, under what license, and with which software. Both groups are format-neutral metadata: provenance and copyright are read from EDI or EMTF XML through the same objects, and the same objects are written back out regardless of target format.

14.2.1. Two Real Provenance Records#

Two real, unrelated surveys in the repository exercise ProvenanceMeta from opposite directions. data/gv_data/xml/gv100.xml is an EMTF XML document already stored in the repository for a 2020 USGS magnetotelluric survey in Gabbs Valley, Nevada; it was produced by converting the genuine field EDI (data/gv_data/gv_final_edi/gv100.edi, itself written by MTpy during USGS processing) through pycsamt’s own EDI adapter, so reading it back exercises the XML reader on real content rather than a hand-written fixture. data/AMT/WILLY_DATA/L18PLT is the historical EDI line used throughout Site and Survey Metadata, produced by a different, unrelated processing chain (MTPROC), and read here straight from its native EDI form.

Note

The Gabbs Valley data is a public-domain USGS release; attribution is required for any use. Cite:

Peacock, J. R., Siler, D. L., Dean, B., Zielinski, L., 2021, Magnetotelluric Data from Gabbs Valley Region, Nevada, 2020: U.S. Geological Survey data release, https://doi.org/10.5066/P9GZ9Z56

>>> from pathlib import Path
>>> from pycsamt.emtf import EMTF
>>> from pycsamt.seg.edi import EDIFile

>>> tf_xml = EMTF.from_xml("data/gv_data/xml/gv100.xml")
>>> print(tf_xml.provenance)
ProvenanceMeta(create_time='2021-06-24T20:24:04.077672+00:00', creating_application='1.1.5', creator=<Person name='Jared Peacock' email=None>, submitter=None, extra=dict(len=0, keys=[]))
>>> print(tf_xml.copyright)
None

>>> edi = EDIFile(Path("data/AMT/WILLY_DATA/L18PLT/18-001A.edi"))
>>> tf_edi = EMTF.from_edi(edi)
>>> print(tf_edi.provenance)
ProvenanceMeta(create_time='11/9/23', creating_application='MTPROC V1.0.7', creator=None, submitter=None, extra=dict(len=0, keys=[]))
>>> print(tf_edi.copyright)
None

Both create_time values are kept exactly as the source file wrote them – an ISO-8601 timestamp with microseconds from the XML file, a bare "11/9/23" from the EDI HEAD.FILEDATE field – rather than being parsed into a stricter type. ProvenanceMeta documents this choice explicitly: inventing a timezone or a day/month order for an ambiguous historical date would add false precision, so the string is preserved verbatim and left for the caller to interpret. The EDI record also has no creator: HEAD.FILEBY is genuinely absent from this file, and the EDI adapter leaves the field None rather than guessing an author from context such as HEAD.ACQBY.

14.2.3. Building a Citation by Hand#

pycsamt cannot invent a citation for the Gabbs Valley file, but the public USGS data release (data/gv_data/gv_survey_v2.xml, an FGDC metadata record distributed with this dataset) has everything needed to build one by hand and attach it explicitly:

>>> from pycsamt.metadata import Reference, CopyrightInfo, Person, Software
>>> from pycsamt.metadata import MetadataError

>>> reference = Reference(
...     author="Peacock, J. R.; Siler, D. L.; Dean, B. J.; Zielinski, L. A.",
...     title="Magnetotelluric Data from the Gabbs Valley Region, Nevada, 2020",
...     year=2021,
...     doi="10.5066/P9GZ9Z56",
... )
>>> print(reference)
<Reference title='Magnetotelluric Data from the Gabbs Valley Region, Nevada, 2020' author='Peacock, J. R.; Siler, D. L.; Dean, B. J.; Zielinski, L. A.' year=2021>
>>> print(reference.to_bibtex("Peacock2021"))
@article{Peacock2021,
  author = {Peacock, J. R.; Siler, D. L.; Dean, B. J.; Zielinski, L. A.},
  title = {Magnetotelluric Data from the Gabbs Valley Region, Nevada, 2020},
  year = {2021},
  doi = {10.5066/P9GZ9Z56},
}

author, title, year, and doi above are copied directly from the FGDC <citeinfo> block (origin, title, pubdate, onlink); nothing is invented. doi is validated against the real DOI syntax at construction, so a malformed identifier is rejected immediately instead of silently stored:

>>> try:
...     Reference(author="x", title="y", doi="not-a-doi")
... except MetadataError as exc:
...     print(type(exc).__name__, exc)
MetadataError Invalid DOI format: not-a-doi

MetadataError is a plain Exception subclass, not a ValueError – unlike the ValueError raised by LocationMeta/SiteMeta in Site and Survey Metadata, so catch it explicitly rather than assuming every metadata class in this package signals invalid input the same way.

Person and Software fill out the picture: a contact for the release, and the software that produced it (recovered here from the plain-text breadcrumbs the same file left in FieldNotesprovenance.software.name = MTpy, provenance.software.author = Jared Peacock – since the structured <Provenance> block only captured the creator’s name, not the software that ran):

>>> contact = Person(
...     name="Jared R. Peacock",
...     email="jpeacock@usgs.gov",
...     organization="U.S. Geological Survey",
... )
>>> print(contact)
<Person name='Jared R. Peacock' email='jpeacock@usgs.gov'>

>>> copyright_info = CopyrightInfo(
...     release_status="Unrestricted Release",
...     conditions_of_use=(
...         "Any use of trade, firm, or product names is for descriptive "
...         "purposes only and does not imply endorsement by the U.S. Government."
...     ),
...     reference=reference,
... )
>>> print(copyright_info)
<CopyrightInfo status='Unrestricted Release'>

>>> software = Software(
...     name="MTpy",
...     version="metadata branch",
...     author=Person(name="Jared Peacock"),
... )
>>> print(software)
<Software name='MTpy' version='metadata branch'>

conditions_of_use is condensed from the FGDC <useconst> field, which in full also disclaims USGS liability for downstream use – shortened here for the example, but a real delivery should carry the complete text. Unlike ProvenanceMeta, which inherits PyCSAMTObject, these four bibliographic classes are plain dataclasses with their own hand-written __repr__ and to_dict; that is why their compact display does not follow the same “cap at eight fields, append ...” convention documented in Site and Survey Metadata.

14.2.4. Enriching and Re-Writing a Document#

Attaching the hand-built citation to the document and writing it back out round-trips cleanly, and now a real <Copyright> element is present because a real CopyrightInfo was actually supplied:

>>> tf_xml.copyright = copyright_info
>>> with TemporaryDirectory() as tmp:
...     out = Path(tmp) / "gv100_enriched.xml"
...     tf_xml.write_xml(out)
...     text = out.read_text(encoding="utf-8")
...     print("<Copyright>" in text)
...     reloaded = EMTF.from_xml(out)
...     print(reloaded.copyright.reference.doi)
...     print(reloaded.copyright.reference.author)
...     print(reloaded.copyright.release_status)
...     print(reloaded.orientation.rotation_info == tf_xml.orientation.rotation_info)
True
10.5066/P9GZ9Z56
Peacock, J. R.; Siler, D. L.; Dean, B. J.; Zielinski, L. A.
Unrestricted Release
True

The pre-existing RotationInfo at the document root survives unchanged alongside the new <Copyright> element – attaching a citation later does not disturb metadata that was already there. tf_xml.copyright = copyright_info mutates the in-memory document directly; nothing is written to disk until write_xml() is called, so the enrichment step and the export step remain two separate, inspectable decisions.

14.2.6. Choosing the Right Object#

Need

Object

Notes

Who/when/what created a document

ProvenanceMeta

create_time kept verbatim; maps to EMTF XML <Provenance>.

A citation for a dataset

Reference

Validates DOI syntax; to_bibtex() for export.

License/usage terms plus a citation

CopyrightInfo

Maps to EMTF XML <Copyright>; never fabricated when absent.

Contact information for an author, submitter, or point of contact

Person

Reused inside both ProvenanceMeta and CopyrightInfo.

The software that produced a document

Software

Standalone record; not the same class as pycsamt.seg.property.Software.

14.2.7. Next Steps#