def _read_sc3ml(filename, id_prefix='smi:org.gfz-potsdam.de/geofon/'): """ Read a SeisComp XML file and returns a :class:`~obspy.core.event.Catalog`. An XSLT file is used to convert the SCXML file to a QuakeML file. The catalog is then generated using the QuakeML module. .. warning:: This function should NOT be called directly, it registers via the the :meth:`~obspy.core.event.catalog.Catalog.write` method of an ObsPy :class:`~obspy.core.event.catalog.Catalog` object, call this instead. :type filename: str :param filename: SCXML file to be read. :type id_prefix: str :param id_prefix: ID prefix. SCXML does not enforce any particular ID restriction, this ID prefix allows to convert the IDs to a well formatted QuakeML ID. You can modify the default ID prefix with the reverse DNS name of your institute. :rtype: :class:`~obspy.core.event.Catalog` :return: An ObsPy Catalog object. .. rubric:: Example >>> from obspy import read_events >>> cat = read_events('/path/to/iris_events.sc3ml') >>> print(cat) 2 Event(s) in Catalog: 2011-03-11T05:46:24.120000Z | +38.297, +142.373 2006-09-10T04:26:33.610000Z | +9.614, +121.961 """ scxml_doc = _xml_doc_from_anything(filename) match = re.match( r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?' r'[0-9]*\.?[0-9]+)}', scxml_doc.tag) try: version = match.group(1) except AttributeError: raise ValueError("Not a SCXML compatible file or string.") else: if version not in SCHEMA_VERSION: message = ("Can't read SCXML version %s, ObsPy can deal with " "versions [%s].") % (version, ', '.join(SCHEMA_VERSION)) raise ValueError(message) xslt_filename = Path(__file__).parent / 'data' xslt_filename = xslt_filename / ('sc3ml_%s__quakeml_1.2.xsl' % version) transform = etree.XSLT(etree.parse(str(xslt_filename))) quakeml_doc = transform(scxml_doc, ID_PREFIX=etree.XSLT.strparam(id_prefix)) return Unpickler().load(io.BytesIO(quakeml_doc))
def _is_sc3ml(path_or_file_object, schema_versions): """ Simple function checking if the passed object contains a valid sc3ml file according to the list of versions given in parameters. Returns True of False. The test is not exhaustive - it only checks the root tag but that should be good enough for most real world use cases. If the schema is used to test for a StationXML file, many real world files are false negatives as they don't adhere to the standard. :type path_or_file_object: str :param path_or_file_object: File name or file like object. :type schema_versions: list of strings :param schema_versions: List of supported SC3ML version. :rtype: bool :return: `True` if file is a SC3ML file. """ if hasattr(path_or_file_object, "tell") and hasattr( path_or_file_object, "seek"): current_position = path_or_file_object.tell() if isinstance(path_or_file_object, etree._Element): xmldoc = path_or_file_object else: try: xmldoc = _xml_doc_from_anything(path_or_file_object) except ValueError: return False finally: # Make sure to reset file pointer position. try: path_or_file_object.seek(current_position, 0) except Exception: pass if hasattr(xmldoc, "getroot"): root = xmldoc.getroot() else: root = xmldoc match = re.match( r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?' r'[0-9]*\.?[0-9]+)}', root.tag) if match is None: return False # Check if schema version is supported version = match.group(1) if version not in schema_versions: warnings.warn('The sc3ml file has version %s, ObsPy can ' 'deal with versions [%s]. Proceed with caution.' % (version, ', '.join(schema_versions))) return True
def validate(path_or_object, version='0.9', verbose=False): """ Check if the given file is a valid SC3ML file. :type path_or_object: str :param path_or_object: File name or file like object. Can also be an etree element. :type version: str :param version: Version of the SC3ML schema to validate against. :type verbose: bool :param verbose: Print error log if True. :rtype: bool :return: `True` if SC3ML file is valid. """ if version not in SUPPORTED_XSD_VERSION: raise ValueError('%s is not a supported version. Use one of these ' 'versions: [%s].' % (version, ', '.join(SUPPORTED_XSD_VERSION))) # Get the schema location. xsd_filename = 'sc3ml_%s.xsd' % version schema_location = os.path.join(os.path.dirname(__file__), 'data', xsd_filename) xmlschema = etree.XMLSchema(etree.parse(schema_location)) if hasattr(path_or_object, "tell") and hasattr(path_or_object, "seek"): current_position = path_or_object.tell() if isinstance(path_or_object, etree._Element): xmldoc = path_or_object else: try: xmldoc = _xml_doc_from_anything(path_or_object) except ValueError: return False finally: # Make sure to reset file pointer position. try: path_or_object.seek(current_position, 0) except Exception: pass valid = xmlschema.validate(xmldoc) # Pretty error printing if the validation fails. if verbose and valid is not True: print("Error validating SC3ML file:") for entry in xmlschema.error_log: print("\t%s" % entry) return valid
def _is_sc3ml(path_or_file_object): """ Simple function checking if the passed object contains a valid sc3ml file according to the list of versions given in parameters. Returns True of False. The test is not exhaustive - it only checks the root tag but that should be good enough for most real world use cases. If the schema is used to test for a StationXML file, many real world files are false negatives as they don't adhere to the standard. :type path_or_file_object: str :param path_or_file_object: File name or file like object. :rtype: bool :return: `True` if file is a SC3ML file. """ if hasattr(path_or_file_object, "tell") and hasattr(path_or_file_object, "seek"): current_position = path_or_file_object.tell() if isinstance(path_or_file_object, etree._Element): xmldoc = path_or_file_object else: try: xmldoc = _xml_doc_from_anything(path_or_file_object) except ValueError: return False finally: # Make sure to reset file pointer position. try: path_or_file_object.seek(current_position, 0) except Exception: pass if hasattr(xmldoc, "getroot"): root = xmldoc.getroot() else: root = xmldoc match = re.match( r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?' r'[0-9]*\.?[0-9]+)}', root.tag) return match is not None
def _read_sc3ml(filename, id_prefix='smi:org.gfz-potsdam.de/geofon/'): """ Read a 0.9 SC3ML file and returns a :class:`~obspy.core.event.Catalog`. An XSLT file is used to convert the SC3ML file to a QuakeML file. The catalog is then generated using the QuakeML module. .. warning:: This function should NOT be called directly, it registers via the the :meth:`~obspy.core.event.catalog.Catalog.write` method of an ObsPy :class:`~obspy.core.event.catalog.Catalog` object, call this instead. :type filename: str :param filename: SC3ML file to be read. :type id_prefix: str :param id_prefix: ID prefix. SC3ML does not enforce any particular ID restriction, this ID prefix allows to convert the IDs to a well formatted QuakeML ID. You can modify the default ID prefix with the reverse DNS name of your institute. :rtype: :class:`~obspy.core.event.Catalog` :return: An ObsPy Catalog object. .. rubric:: Example >>> from obspy import read_events >>> cat = read_events('/path/to/iris_events.sc3ml') >>> print(cat) 2 Event(s) in Catalog: 2011-03-11T05:46:24.120000Z | +38.297, +142.373 2006-09-10T04:26:33.610000Z | +9.614, +121.961 """ xslt_filename = os.path.join(os.path.dirname(__file__), 'data', 'sc3ml_0.9__quakeml_1.2.xsl') transform = etree.XSLT(etree.parse(xslt_filename)) sc3ml_doc = _xml_doc_from_anything(filename) quakeml_doc = transform(sc3ml_doc, ID_PREFIX=etree.XSLT.strparam(id_prefix)) return Unpickler().load(io.BytesIO(quakeml_doc))
def validate(path_or_object, version=None, verbose=False): """ Check if the given file is a valid SC3ML file. :type path_or_object: str :param path_or_object: File name or file like object. Can also be an etree element. :type version: str :param version: Version of the SC3ML schema to validate against. :type verbose: bool :param verbose: Print error log if True. :rtype: bool :return: `True` if SC3ML file is valid. """ if hasattr(path_or_object, "tell") and hasattr(path_or_object, "seek"): current_position = path_or_object.tell() if isinstance(path_or_object, etree._Element): xmldoc = path_or_object else: try: xmldoc = _xml_doc_from_anything(path_or_object) except ValueError: return False finally: # Make sure to reset file pointer position. try: path_or_object.seek(current_position, 0) except Exception: pass # Read version number from file if version is None: match = re.match( r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?' r'[0-9]*\.?[0-9]+)}', xmldoc.tag) try: version = match.group(1) except AttributeError: raise ValueError("Not a SC3ML compatible file or string.") if version not in SUPPORTED_XSD_VERSION: raise ValueError('%s is not a supported version. Use one of these ' 'versions: [%s].' % (version, ', '.join(SUPPORTED_XSD_VERSION))) # Get the schema location. xsd_filename = 'sc3ml_%s.xsd' % version schema_location = os.path.join(os.path.dirname(__file__), 'data', xsd_filename) xmlschema = etree.XMLSchema(etree.parse(schema_location)) valid = xmlschema.validate(xmldoc) # Pretty error printing if the validation fails. if verbose and valid is not True: print("Error validating SC3ML file:") for entry in xmlschema.error_log: print("\t%s" % entry) return valid
def validate(path_or_object, version=None, verbose=False): """ Check if the given file is a valid SC3ML file. :type path_or_object: str :param path_or_object: File name or file like object. Can also be an etree element. :type version: str :param version: Version of the SC3ML schema to validate against. :type verbose: bool :param verbose: Print error log if True. :rtype: bool :return: `True` if SC3ML file is valid. """ if hasattr(path_or_object, "tell") and hasattr(path_or_object, "seek"): current_position = path_or_object.tell() if isinstance(path_or_object, etree._Element): xmldoc = path_or_object else: try: xmldoc = _xml_doc_from_anything(path_or_object) except ValueError: return False finally: # Make sure to reset file pointer position. try: path_or_object.seek(current_position, 0) except Exception: pass # Read version number from file if version is None: match = re.match( r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?' r'[0-9]*\.?[0-9]+)}', xmldoc.tag) try: version = match.group(1) except AttributeError: raise ValueError("Not a SC3ML compatible file or string.") if version not in SUPPORTED_XSD_VERSION: raise ValueError('%s is not a supported version. Use one of these ' 'versions: [%s].' % (version, ', '.join(SUPPORTED_XSD_VERSION))) # Get the schema location. xsd_filename = 'sc3ml_%s.xsd' % version schema_location = os.path.join(os.path.dirname(__file__), 'data', xsd_filename) xmlschema = etree.XMLSchema(etree.parse(schema_location)) valid = xmlschema.validate(xmldoc) # Pretty error printing if the validation fails. if verbose and valid is not True: print("Error validating SC3ML file:") for entry in xmlschema.error_log: print("\t%s" % entry) return valid