├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── codecov.yml ├── dependabot.yml └── workflows │ ├── check.yml │ ├── docs.yml │ ├── pypi-publish.yml │ └── tests.yml ├── .gitignore ├── CITATION.cff ├── HinetPy ├── __init__.py ├── channel.py ├── client.py ├── header.py ├── utils.py └── win32.py ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── docs ├── Makefile ├── _templates │ └── layout.html ├── api.rst ├── api │ ├── HinetPy.channel.rst │ ├── HinetPy.client.rst │ ├── HinetPy.header.rst │ ├── HinetPy.utils.rst │ └── HinetPy.win32.rst ├── appendix.rst ├── appendix │ ├── catwin32.rst │ ├── channeltable.rst │ ├── response.rst │ └── win2sac.rst ├── changelog.rst ├── conf.py ├── examples.rst ├── examples │ ├── events.csv │ ├── example1.py │ ├── example1.rst │ ├── example2.py │ └── example2.rst ├── index.rst ├── installation.rst ├── license.rst ├── locale │ └── zh_CN │ │ └── LC_MESSAGES │ │ ├── api.po │ │ ├── appendix.po │ │ ├── appendix │ │ ├── catwin32.po │ │ ├── channeltable.po │ │ ├── response.po │ │ └── win2sac.po │ │ ├── changelog.po │ │ ├── examples.po │ │ ├── examples │ │ ├── example1.po │ │ └── example2.po │ │ ├── index.po │ │ ├── installation.po │ │ ├── license.po │ │ ├── tutorial.po │ │ └── tutorial │ │ ├── conversion.po │ │ ├── get-catalog.po │ │ ├── get-continuous-waveform.po │ │ ├── get-event-waveform.po │ │ └── get-started.po ├── tutorial.rst └── tutorial │ ├── conversion.rst │ ├── get-catalog.rst │ ├── get-continuous-waveform.rst │ ├── get-event-waveform.rst │ └── get-started.rst ├── paper ├── paper.bib └── paper.md ├── pyproject.toml ├── requirements-dev.txt ├── requirements.txt └── tests ├── __init__.py ├── localtest_channels.py ├── localtest_client_multi_threads.py ├── test_channel.py ├── test_client.py ├── test_client_nologin.py ├── test_utils.py └── test_win32.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a problem/bug to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Description of the problem** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | **Full code that generated the error** 15 | 16 | *Please be careful not to post your real username and password in the codes.* 17 | 18 | ```python 19 | PASTE CODE HERE 20 | ``` 21 | 22 | **Full error message** 23 | 24 | ``` 25 | PASTE ERROR MESSAGE HERE 26 | ``` 27 | 28 | **Expected behavior** 29 | 30 | A clear and concise description of what you expected to happen. 31 | 32 | **System information** 33 | 34 | - OS: Windows | Linux | macOS 35 | - Python version: `python --version` 36 | - HinetPy version: `python -c "import HinetPy; print(HinetPy.__version__)"` 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Request the addtion of a new feature 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Description of the desired feature** 11 | 12 | A clear and concise description of what you need. 13 | 14 | **Description of the solution you'd like** 15 | 16 | A clear and concise description of what you want to happen. 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description of proposed changes** 2 | 3 | 4 | 5 | 6 | Fixes # 7 | 8 | 9 | **Reminders** 10 | 11 | - [ ] Run `make format` and `make check` to make sure the code follows the style guide. 12 | - [ ] Add tests for new features or tests that would have caught the bug that you're fixing. 13 | - [ ] Write detailed docstrings for all functions/methods. 14 | - [ ] If adding new functionality, add an example to docstrings or tutorials. 15 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | notify: 3 | require_ci_to_pass: no 4 | 5 | coverage: 6 | status: 7 | project: 8 | default: 9 | target: auto # increase overall coverage on each pull request 10 | threshold: 0.25% # Allow the coverage to drop by X% 11 | if_not_found: success 12 | if_ci_failed: failure 13 | patch: 14 | default: 15 | target: 90% # >=90% of new changes should be tested 16 | if_not_found: success 17 | if_ci_failed: failure 18 | 19 | comment: off 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions 2 | 3 | version: 2 4 | updates: 5 | 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | # Check for updates to GitHub Actions every weekday 10 | interval: "weekly" 11 | day: "tuesday" 12 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Code lint and style checks 3 | # 4 | name: Check 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | pull_request: 10 | workflow_dispatch: 11 | 12 | jobs: 13 | check: 14 | name: Code Styles 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Set up Python 3.x 22 | uses: actions/setup-python@v5 23 | with: 24 | python-version: '3.x' 25 | 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install -r requirements.txt 29 | python -m pip install ruff 30 | 31 | - name: Check code style 32 | run: make check 33 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Build and deploy documentation 3 | # 4 | name: Docs 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | paths: 10 | - 'HinetPy/*.py' 11 | - 'docs/**' 12 | - 'README.rst' 13 | pull_request: 14 | paths: 15 | - 'HinetPy/*.py' 16 | - 'docs/**' 17 | - 'README.rst' 18 | workflow_dispatch: 19 | 20 | concurrency: 21 | group: ${{ github.workflow }}-${{ github.ref }} 22 | cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} 23 | 24 | jobs: 25 | deploy-docs: 26 | name: Docs 27 | runs-on: ubuntu-latest 28 | 29 | steps: 30 | - name: Checkout 31 | uses: actions/checkout@v4 32 | with: 33 | # fecth all history so that setuptools-scm works 34 | fetch-depth: 0 35 | 36 | - name: Set up Python 3.x 37 | uses: actions/setup-python@v5 38 | with: 39 | python-version: '3.x' 40 | 41 | - name: Install dependencies 42 | run: | 43 | python -m pip install -r requirements.txt 44 | python -m pip install build sphinx sphinx-intl sphinx_rtd_theme 45 | python -m build --sdist 46 | python -m pip install dist/* 47 | 48 | - name: Build documentation 49 | run: make doc 50 | 51 | - name: Deploy to GitHub Pages 52 | uses: peaceiris/actions-gh-pages@v4.0.0 53 | # Only deploy on main branch 54 | if: github.ref == 'refs/heads/main' 55 | with: 56 | github_token: ${{ secrets.GITHUB_TOKEN }} 57 | publish_branch: gh-pages 58 | publish_dir: ./docs/_build/html 59 | -------------------------------------------------------------------------------- /.github/workflows/pypi-publish.yml: -------------------------------------------------------------------------------- 1 | # Publish to PyPI 2 | name: Publish to PyPI 3 | 4 | on: 5 | release: 6 | types: 7 | - published 8 | 9 | jobs: 10 | publish-pypi: 11 | runs-on: ubuntu-latest 12 | if: github.repository == 'seisman/HinetPy' 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Set up Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: '3.x' 21 | 22 | - name: Build 23 | run: | 24 | python -m pip install build 25 | python -m build 26 | ls -lh dist/ 27 | 28 | - name: Publish to PyPI 29 | if: startsWith(github.ref, 'refs/tags') 30 | uses: pypa/gh-action-pypi-publish@v1.12.4 31 | with: 32 | password: ${{ secrets.PYPI_API_TOKEN }} 33 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - 'HinetPy/**' 8 | - 'tests/**' 9 | - '.github/workflows/tests.yml' 10 | pull_request: 11 | branches: [main] 12 | paths: 13 | - 'HinetPy/**' 14 | - 'tests/**' 15 | - '.github/workflows/tests.yml' 16 | workflow_dispatch: 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} 21 | 22 | jobs: 23 | test: 24 | name: ${{ matrix.os }} - Python ${{ matrix.python-version }} 25 | runs-on: ${{ matrix.os }} 26 | strategy: 27 | max-parallel: 1 # Hinet doesn't allow parallel data request 28 | fail-fast: false 29 | matrix: 30 | python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] 31 | #python-version: ["3.8", "3.12"] 32 | os: [macos-latest, ubuntu-latest] 33 | 34 | steps: 35 | - name: Checkout 36 | uses: actions/checkout@v4 37 | with: 38 | # fecth all history so that setuptools-scm works 39 | fetch-depth: 0 40 | 41 | - name: Set up Python ${{ matrix.python-version }} 42 | uses: actions/setup-python@v5 43 | with: 44 | python-version: ${{ matrix.python-version }} 45 | 46 | - name: Install dependencies 47 | run: | 48 | python -m pip install -r requirements.txt 49 | python -m pip install --upgrade certifi 50 | python -m pip install build pytest pytest-cov 51 | python -m build --sdist 52 | python -m pip install dist/* 53 | 54 | - name: Install win32tools 55 | run: | 56 | # Download win32tools 57 | python -c "from HinetPy import Client; Client('${{ secrets.HINET_USERNAME }}', '${{ secrets.HINET_PASSWORD }}')._get_win32tools()" 58 | # Compile and install win32tools 59 | tar -xf win32tools.tar.gz && rm win32tools.tar.gz 60 | # patch the win2sac source code on macOS 61 | if [ "$RUNNER_OS" == "macOS" ]; then sed -i.bak 's/malloc.h/stdlib.h/' win32tools/win2sac.src/s4read_data.c; fi 62 | cd win32tools; make; mkdir bin; mv catwin32.src/catwin32 win2sac.src/win2sac_32 bin/; cd .. 63 | # Add to PATH 64 | echo "${{ github.workspace }}/win32tools/bin" >> $GITHUB_PATH 65 | 66 | - name: Run tests 67 | run: make test 68 | env: 69 | HINET_USERNAME: ${{ secrets.HINET_USERNAME }} 70 | HINET_PASSWORD: ${{ secrets.HINET_PASSWORD }} 71 | 72 | - name: Upload coverage reports 73 | uses: codecov/codecov-action@v4 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | *.py[cd] 3 | 4 | # Distribution / packaging 5 | build/ 6 | dist/ 7 | *.egg 8 | *.egg-info/ 9 | .eggs/ 10 | 11 | # Unit test / coverage reports 12 | .cache 13 | htmlcov/ 14 | .coverage* 15 | coverage.xml 16 | 17 | # Sphinx documentation 18 | _build/ 19 | *.mo 20 | 21 | # Backup copies / swap files 22 | *~ 23 | .*.swp 24 | 25 | # macOS 26 | .DS_Store 27 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # YAML 1.2 2 | # Metadata for citation of this software according to the CFF format (https://citation-file-format.github.io/) 3 | cff-version: "1.2.0" 4 | message: If you use this software, please cite our article in the Journal of Open Source Software. 5 | title: "HinetPy: A Python package for accessing and processing NIED Hi-net seismic data" 6 | authors: 7 | - family-names: Tian 8 | given-names: Dongdong 9 | orcid: "https://orcid.org/0000-0001-7967-1197" 10 | version: 0.10.0 11 | date-released: 2024-11-21 12 | doi: 10.5281/zenodo.14193527 13 | type: software 14 | license: MIT 15 | repository-code: "https://github.com/seisman/HinetPy" 16 | preferred-citation: 17 | title: "HinetPy: A Python package for accessing and processing NIED Hi-net seismic data" 18 | authors: 19 | - family-names: Tian 20 | given-names: Dongdong 21 | orcid: "https://orcid.org/0000-0001-7967-1197" 22 | date-published: 2024-06-25 23 | doi: 10.21105/joss.06840 24 | volume: 9 25 | issue: 98 26 | start: 6840 27 | journal: Journal of Open Source Software 28 | issn: 2475-9066 29 | publisher: 30 | name: Open Journals 31 | type: article 32 | url: "https://joss.theoj.org/papers/10.21105/joss.06840" 33 | -------------------------------------------------------------------------------- /HinetPy/__init__.py: -------------------------------------------------------------------------------- 1 | # noqa: N999 2 | """ 3 | HinetPy 4 | ======= 5 | 6 | HinetPy is a Python package for accessing and processing NIED Hi-net seismic data. 7 | 8 | Basis usage: 9 | 10 | >>> from HinetPy import Client, win32 11 | >>> from datetime import datetime 12 | >>> # You need to provide your Hi-net username and password here! 13 | >>> client = Client("username", "password") 14 | >>> starttime = datetime(2010, 1, 1, 0, 0) 15 | >>> data, ctable = client.get_continuous_waveform("0101", starttime, 20) 16 | >>> win32.extract_sac(data, ctable) 17 | >>> win32.extract_sacpz(ctable) 18 | """ 19 | 20 | from importlib.metadata import version 21 | 22 | from .client import Client 23 | from .header import NETWORK 24 | 25 | __all__ = ["NETWORK", "Client", "win32"] 26 | # Get semantic version through setuptools-scm 27 | __version__ = f'v{version("HinetPy")}' # e.g. v0.1.2.dev3+g0ab3cd78 28 | -------------------------------------------------------------------------------- /HinetPy/channel.py: -------------------------------------------------------------------------------- 1 | """ 2 | Class for channels. 3 | """ 4 | 5 | from __future__ import annotations 6 | 7 | import math 8 | import warnings 9 | 10 | 11 | class Channel: 12 | """ 13 | Information for a single channel. 14 | """ 15 | 16 | def __init__( # noqa: PLR0913 17 | self, 18 | id: str, # noqa: A002 19 | name: str, 20 | component: str, 21 | latitude: float | str, 22 | longitude: float | str, 23 | unit: str, 24 | gain: float | str, 25 | damping: float | str, 26 | period: float | str, 27 | preamplification: float | str, 28 | lsb_value: float | str, 29 | ): 30 | """ 31 | Parameters 32 | ---------- 33 | id 34 | Channel ID. 35 | name 36 | Station Name. 37 | component 38 | Channel component name (e.g., ``U``, ``N`` or ``E``). 39 | latitude 40 | Station latitude. 41 | longitude 42 | Station longitude. 43 | unit 44 | Unit of data (e.g., ``m``, ``m/s``, ``m/s/s``, ``rad``). 45 | gain 46 | Sensor sensitivity. 47 | damping 48 | Damping constant of the sensor. 49 | period 50 | Natural period of the seismometer. 51 | preamplification 52 | Preamplification value. 53 | lsb_value 54 | LSB value. 55 | 56 | Notes 57 | ----- 58 | The Hi-net website uses the moving-coil velocity-type seismometer. See 59 | :doc:`/appendix/response` for details. 60 | """ 61 | self.id = id 62 | self.name = name 63 | self.component = component 64 | self.latitude = float(latitude) 65 | self.longitude = float(longitude) 66 | self.unit = unit 67 | self.gain = float(gain) 68 | self.damping = float(damping) 69 | self.period = float(period) 70 | self.preamplification = float(preamplification) 71 | self.lsb_value = float(lsb_value) 72 | 73 | def _get_polezero(self): 74 | """ 75 | Determine the polezero parameters. 76 | """ 77 | # Calculate natural frequency 78 | freq = 2.0 * math.pi / self.period 79 | 80 | # Calculate poles by finding roots of equation s^2+2hws+w^2=0 81 | self.zeros = 3 82 | self.poles = 2 83 | self.real = 0.0 - self.damping * freq 84 | self.imaginary = freq * math.sqrt(1.0 - self.damping**2.0) 85 | 86 | # Calculate the CONSTANT 87 | fn = 20.0 # alaways assume normalization frequency is 20 Hz 88 | s = complex(0, 2 * math.pi * fn) 89 | self.a0 = abs((s**2 + 2 * self.damping * freq * s + freq**2) / s**2) 90 | self.sensitivity = ( 91 | self.gain * math.pow(10, self.preamplification / 20.0) / self.lsb_value 92 | ) 93 | 94 | def write_sacpz(self, pzfile, keep_sensitivity=False): 95 | """ 96 | Write channel information into a SAC polezero file. 97 | 98 | Parameters 99 | ---------- 100 | pzfile: str 101 | Name of the SAC polezero file. 102 | k9.999513e-01eep_sensitivity: bool 103 | Keep sensitivity in the SAC polezero "CONSTANT" or not. 104 | """ 105 | chan_info = f"{self.name}.{self.component} ({self.id})" 106 | # Hi-net uses a moving-coil velocity-type seismometer. 107 | if self.unit != "m/s": 108 | msg = f"{chan_info}: Unit is not velocity. The PZ file may be wrong." 109 | warnings.warn(msg, category=RuntimeWarning, stacklevel=2) 110 | if self.period == 0.0: 111 | msg = f"{chan_info}): Natural period = 0.0. Skipped." 112 | warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2) 113 | return 114 | 115 | self._get_polezero() 116 | constant = self.a0 * self.sensitivity if keep_sensitivity else self.a0 117 | # write information to a SAC PZ file 118 | with open(pzfile, "w", encoding="utf8") as pz: 119 | pz.write(f"ZEROS {self.zeros}\n") 120 | pz.write(f"POLES {self.poles}\n") 121 | pz.write(f"{self.real:9.6f} {self.imaginary:9.6f}\n") 122 | pz.write(f"{self.real:9.6f} {-self.imaginary:9.6f}\n") 123 | pz.write(f"CONSTANT {constant:e}\n") 124 | -------------------------------------------------------------------------------- /HinetPy/header.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module provides a dict of seismic networks that are available from the Hi-net 3 | website. 4 | 5 | The dict is named ``NETWORK``. The network code is the key of the dict, and the value is 6 | a :class:`~HinetPy.header.Network` object, which contains the network name, number of 7 | channels, start time when waveform data is available, and the homepage URL. The network 8 | code is a string, e.g., "0101" for Hi-net. The number of channels, start time, and 9 | homepage URL are obtained from the Hi-net website, but they may not be up-to-date so 10 | don't rely on them too much. 11 | 12 | To view the list of supported networks, use: 13 | 14 | >>> from HinetPy import NETWORK 15 | >>> for code in NETWORK.keys(): 16 | ... print(code, NETWORK[code].name) 17 | 0101 NIED Hi-net 18 | 0103 NIED F-net (broadband) 19 | 0103A NIED F-net (strong motion) 20 | 0106 NIED Temp. obs. in eastern Shikoku 21 | 0120 NIED S-net (velocity)... 22 | """ 23 | 24 | from __future__ import annotations 25 | 26 | from datetime import datetime 27 | 28 | 29 | class Network: 30 | def __init__( 31 | self, name: str, channels: int | None, starttime: str | datetime, url: str 32 | ): 33 | """ 34 | A seismic network and its information. 35 | 36 | Parameters 37 | ---------- 38 | name 39 | Network name. 40 | channels 41 | Number of channels the network has. 42 | starttime 43 | Start time (JST: UTC+0900) when waveform data is avaiable. 44 | url 45 | Homepage of the network. 46 | """ 47 | self.name = name 48 | self.channels = channels 49 | self.starttime = starttime 50 | self.url = url 51 | 52 | 53 | URL = { 54 | "Hinet": "http://www.hinet.bosai.go.jp", 55 | "Fnet": "http://www.fnet.bosai.go.jp", 56 | "Vnet": "http://www.vnet.bosai.go.jp", 57 | "JMA": "http://www.jma.go.jp/jma/indexe.html", 58 | "Snet": "https://www.seafloor.bosai.go.jp/", 59 | } 60 | JMA_VNET = "JMA Volcanic Seismometer Network " 61 | 62 | # fmt: off 63 | _networks = [ 64 | ("0101", "NIED Hi-net", 2336, "20040401", URL["Hinet"]), 65 | ("0103", "NIED F-net (broadband)", 438, "20040401", URL["Fnet"]), 66 | ("0103A", "NIED F-net (strong motion)", 438, "20040401", URL["Fnet"]), 67 | ("010501", "NIED V-net (Tokachidake)", 33, "20100401", URL["Vnet"]), 68 | ("010502", "NIED V-net (Tarumaesan)", 33, "20100401", URL["Vnet"]), 69 | ("010503", "NIED V-net (Usuzan)", 33, "20100401", URL["Vnet"]), 70 | ("010504", "NIED V-net (Hokkaido-Komagatake)", 33, "20100401", URL["Vnet"]), 71 | ("010505", "NIED V-net (Iwatesan)", 33, "20100401", URL["Vnet"]), 72 | ("010506", "NIED V-net (Nasudake)", 42, "20100401", URL["Vnet"]), 73 | ("010507", "NIED V-net (Asamayama)", 33, "20100401", URL["Vnet"]), 74 | ("010508", "NIED V-net (Kusatsu-Shiranesan)", 33, "20100401", URL["Vnet"]), 75 | ("010509", "NIED V-net (Fujisan)", 57, "20100401", URL["Vnet"]), 76 | ("010510", "NIED V-net (Miyakejima)", 40, "20100401", URL["Vnet"]), 77 | ("010511", "NIED V-net (Izu-Oshima)", 39, "20100401", URL["Vnet"]), 78 | ("010512", "NIED V-net (Asosan)", 44, "20100401", URL["Vnet"]), 79 | ("010513", "NIED V-net (Unzendake)", 33, "20100401", URL["Vnet"]), 80 | ("010514", "NIED V-net (Kirishimayama)", 22, "20100401", URL["Vnet"]), 81 | ("0106", "NIED Temp. obs. in eastern Shikoku", 15, "20151013", "https://doi.org/10.17598/NIED.0027"), 82 | ("0120", "NIED S-net (velocity)", 450, "20160815", URL["Hinet"]), 83 | ("0120A", "NIED S-net (acceleration)", 450, "20160815", URL["Hinet"]), 84 | ("0120B", "NIED S-net (acceleration 2LG)", 450, "20160815", URL["Hinet"]), 85 | ("0120C", "NIED S-net (acceleration 2HG)", 450, "20160815", URL["Hinet"]), 86 | ("0131", "NIED MeSO-net", 900, "20170401", URL["Hinet"]), 87 | ("0201", "Hokkaido University", 205, "20040401", "http://www.sci.hokudai.ac.jp/isv/english/"), 88 | ("0202", "Tohoku University", 157, "20040401", "http://www.aob.geophys.tohoku.ac.jp/aob-e/"), 89 | ("0203", "Tokyo University", 316, "20040401", "http://www.eri.u-tokyo.ac.jp/eng/"), 90 | ("0204", "Kyoto University", 196, "20040401", "http://www.dpri.kyoto-u.ac.jp/en/"), 91 | ("0205", "Kyushu University", 73, "20040401", "http://www.sevo.kyushu-u.ac.jp/index-e.html"), 92 | ("0206", "Hirosaki University", 13, "20040401", "http://hrsryu.geo.hirosaki-u.ac.jp/"), 93 | ("0207", "Nagoya University", 75, "20040401", "http://www.seis.nagoya-u.ac.jp/index_e/"), 94 | ("0208", "Kochi University", 34, "20040401", "http://www-en.kochi-u.ac.jp/"), 95 | ("0209", "Kagoshima University", 48, "20040401", "http://leopard.sci.kagoshima-u.ac.jp/noev/English/home.htm"), 96 | ("0231", "MeSO-net (~2017.03)", 900, "20080516", ""), 97 | ("0301", "JMA Seismometer Network", 872, "20040401", URL["JMA"]), 98 | ("030201", JMA_VNET + "(Atosanupuri)", 18, "20101201", URL["JMA"]), 99 | ("030202", JMA_VNET + "(Meakandake)", 16, "20101201", URL["JMA"]), 100 | ("030203", JMA_VNET + "(Taisetsuzan)", 9, "20101201", URL["JMA"]), 101 | ("030204", JMA_VNET + "(Tokachidake)", 32, "20101201", URL["JMA"]), 102 | ("030205", JMA_VNET + "(Tarumaesan)", 27, "20101201", URL["JMA"]), 103 | ("030206", JMA_VNET + "(Kuttara)", 15, "20101201", URL["JMA"]), 104 | ("030207", JMA_VNET + "(Usuzan)", 24, "20101201", URL["JMA"]), 105 | ("030208", JMA_VNET + "(Hokkaido-Komagatake)", 30, "20101201", URL["JMA"]), 106 | ("030209", JMA_VNET + "(Esan)", 14, "20101201", URL["JMA"]), 107 | ("030210", JMA_VNET + "(Iwakisan)", 9, "20101201", URL["JMA"]), 108 | ("030211", JMA_VNET + "(Akita-Yakeyama)", 11, "20101201", URL["JMA"]), 109 | ("030212", JMA_VNET + "(Iwatesan)", 17, "20101201", URL["JMA"]), 110 | ("030213", JMA_VNET + "(Akita-Komagatake)", 14, "20101201", URL["JMA"]), 111 | ("030214", JMA_VNET + "(Chokaisan)", 6, "20101201", URL["JMA"]), 112 | ("030215", JMA_VNET + "(Kurikomayama)", 11, "20101201", URL["JMA"]), 113 | ("030216", JMA_VNET + "(Zaozan)", 15, "20101201", URL["JMA"]), 114 | ("030217", JMA_VNET + "(Azumayama)", 28, "20101201", URL["JMA"]), 115 | ("030218", JMA_VNET + "(Adatarayama)", 19, "20101201", URL["JMA"]), 116 | ("030219", JMA_VNET + "(Bandaisan)", 18, "20101201", URL["JMA"]), 117 | ("030220", JMA_VNET + "(Nasudake)", 15, "20101201", URL["JMA"]), 118 | ("030221", JMA_VNET + "(Nikko-Shiranesan)", 11, "20101201", URL["JMA"]), 119 | ("030222", JMA_VNET + "(Kusatsu-Shiranesan)", 21, "20101201", URL["JMA"]), 120 | ("030223", JMA_VNET + "(Asamayama)", 44, "20101201", URL["JMA"]), 121 | ("030224", JMA_VNET + "(Niigata-Yakeyama)", 14, "20101201", URL["JMA"]), 122 | ("030225", JMA_VNET + "(Yakedake)", 15, "20101201", URL["JMA"]), 123 | ("030226", JMA_VNET + "(Norikuradake)", 9, "20101201", URL["JMA"]), 124 | ("030227", JMA_VNET + "(Ontakesan)", 40, "20101201", URL["JMA"]), 125 | ("030228", JMA_VNET + "(Hakusan)", 10, "20101201", URL["JMA"]), 126 | ("030229", JMA_VNET + "(Fujisan)", 27, "20101201", URL["JMA"]), 127 | ("030230", JMA_VNET + "(Hakoneyama)", 11, "20101201", URL["JMA"]), 128 | ("030231", JMA_VNET + "(Izu-Tobu Volcanoes)", 18, "20101201", URL["JMA"]), 129 | ("030232", JMA_VNET + "(Izu-Oshima)", 22, "20101201", URL["JMA"]), 130 | ("030233", JMA_VNET + "(Niijima)", 9, "20101201", URL["JMA"]), 131 | ("030234", JMA_VNET + "(Kozushima)", 9, "20101201", URL["JMA"]), 132 | ("030235", JMA_VNET + "(Miyakejima)", 19, "20101201", URL["JMA"]), 133 | ("030236", JMA_VNET + "(Hachijojima)", 11, "20101201", URL["JMA"]), 134 | ("030237", JMA_VNET + "(Aogashima)", 9, "20101201", URL["JMA"]), 135 | ("030238", JMA_VNET + "(Tsurumidake and Garandake)", 16, "20101201", URL["JMA"]), 136 | ("030239", JMA_VNET + "(Kujusan)", 13, "20101201", URL["JMA"]), 137 | ("030240", JMA_VNET + "(Asosan)", 31, "20101201", URL["JMA"]), 138 | ("030241", JMA_VNET + "(Unzendake)", 28, "20101201", URL["JMA"]), 139 | ("030242", JMA_VNET + "(Kirishimayama)", 66, "20101201", URL["JMA"]), 140 | ("030243", JMA_VNET + "(Sakurajima)", 31, "20101201", URL["JMA"]), 141 | ("030244", JMA_VNET + "(Satsuma-Iojima)", 16, "20101201", URL["JMA"]), 142 | ("030245", JMA_VNET + "(Kuchinoerabujima)", 29, "20101201", URL["JMA"]), 143 | ("030246", JMA_VNET + "(Suwanosejima)", 12, "20101201", URL["JMA"]), 144 | ("030247", JMA_VNET + "(Hakkodasan)", 18, "20101201", URL["JMA"]), 145 | ("030248", JMA_VNET + "(Towada)", 9, "20101201", URL["JMA"]), 146 | ("030249", JMA_VNET + "(Midagahara)", 9, "20101201", URL["JMA"]), 147 | ("0401", "JAMSTEC Realtime Data from the Deep Sea Floor Observatory", 73, "20040401", "http://www.jamstec.go.jp/e/index.html"), 148 | ("0402", "NIED DONET1 (broadband)", 132, "20160401", URL["Snet"]), 149 | ("0402A", "NIED DONET1 (strong motion)", 132, "20160401", URL["Snet"]), 150 | ("0402N", "JAMSTEC NIED DONET1 (broadband)", 132, "20160401", URL["Snet"]), 151 | ("0402AN", "JAMSTEC NIED DONET1 (strong motion)", 132, "20160401", URL["Snet"]), 152 | ("0403", "NIED DONET2 (broadband)", 174, "20160401", URL["Snet"]), 153 | ("0403A", "NIED DONET2 (strong motion)", 174, "20160401", URL["Snet"]), 154 | ("0403N", "JAMSTEC NIED DONET2 (broadband)", 174, "20160401", URL["Snet"]), 155 | ("0403AN", "JAMSTEC NIED DONET2 (strong motion)", 174, "20160401", URL["Snet"]), 156 | ("0501", "AIST", 84, "20040401", "http://www.aist.go.jp/index_en.html"), 157 | ("0601", "GSI", 6, "20040401", "http://www.gsi.go.jp/ENGLISH/index.html"), 158 | ("0701", "Tokyo Metropolitan Government", 54, "20040401", "http://www.metro.tokyo.jp/ENGLISH/index.htm"), 159 | ("0702", "Hot Spring Research Institute of Kanagawa Prefecture", 42, "20040401", "http://www.onken.odawara.kanagawa.jp/"), 160 | ("0703", "Aomori Prefectural Government", 15, "20040401", "http://www.pref.aomori.lg.jp/foreigners/"), 161 | ("0705", "Shizuoka Prefectural Government", 3, "20040615", "http://www.pref.shizuoka.jp/a_foreign/english/"), 162 | ("0801", "ADEP", 780, "20150101", "http://www.adep.or.jp/"), 163 | ] 164 | # fmt: on 165 | 166 | NETWORK = { 167 | code: Network(name, channels, datetime.strptime(starttime, "%Y%m%d"), url) 168 | for code, name, channels, starttime, url in _networks 169 | } 170 | -------------------------------------------------------------------------------- /HinetPy/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utility functions. 3 | """ 4 | 5 | from __future__ import annotations 6 | 7 | import math 8 | import shutil 9 | from datetime import date, datetime 10 | from importlib.metadata import version 11 | 12 | import requests 13 | from packaging.version import Version 14 | 15 | 16 | def split_integer(number: int, maxn: int) -> list[int]: 17 | """ 18 | Split an integer into evenly sized chunks. 19 | 20 | Parameters 21 | ---------- 22 | number 23 | An interger that to be split into chunks. 24 | maxn 25 | The maximum number in each chunk. 26 | 27 | Returns 28 | ------- 29 | chunks 30 | List of integers. 31 | 32 | Examples 33 | -------- 34 | >>> split_integer(12, 3) 35 | [3, 3, 3, 3] 36 | >>> split_integer(15, 4) 37 | [4, 4, 4, 3] 38 | """ 39 | count = math.ceil(number / maxn) 40 | chunks = [number // count for i in range(count)] 41 | for i in range(number % count): 42 | chunks[i] += 1 43 | return chunks 44 | 45 | 46 | def point_inside_box( 47 | latitude: float, 48 | longitude: float, 49 | minlatitude: float | None = None, 50 | maxlatitude: float | None = None, 51 | minlongitude: float | None = None, 52 | maxlongitude: float | None = None, 53 | ) -> bool: 54 | """ 55 | Check if a point is inside a box region. 56 | 57 | Parameters 58 | ---------- 59 | latitude 60 | Latitude of the point. 61 | longitude 62 | Longitude of the point. 63 | minlatitude 64 | Minimum latitude of the box region. 65 | maxlatitude 66 | Maximum latitude of the box region. 67 | minlongitude 68 | Minimum longitude of the box region. 69 | maxlongitude 70 | Maximum longitude of the box region. 71 | 72 | Returns 73 | ------- 74 | bool 75 | True if the point is inside the box region. 76 | 77 | Examples 78 | -------- 79 | >>> point_inside_box(40, 130) 80 | True 81 | >>> point_inside_box(40, 130, 0, 50, 100, 150) 82 | True 83 | >>> point_inside_box(40, 130, 0, 30, 100, 150) 84 | False 85 | >>> point_inside_box(40, -130, maxlongitude=150) 86 | False 87 | >>> point_inside_box(40, -130, maxlongitude=300) 88 | True 89 | """ 90 | if (minlongitude and minlongitude < 0.0) or (maxlongitude and maxlongitude < 0.0): 91 | raise ValueError("minlongitude and maxlongitude should be in 0-360.") 92 | longitude = longitude + 360.0 if longitude < 0.0 else longitude 93 | 94 | if minlatitude and latitude < minlatitude: 95 | return False 96 | if maxlatitude and latitude > maxlatitude: 97 | return False 98 | if minlongitude and longitude < minlongitude: 99 | return False 100 | return not (maxlongitude and longitude > maxlongitude) 101 | 102 | 103 | def haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float: 104 | """ 105 | Calculate the great circle distance between two points on the earth (specified in 106 | decimal degrees) using haversine formula. 107 | 108 | Reference: https://stackoverflow.com/a/4913653/7770208. 109 | 110 | >>> haversine(40, 130, 50, 140) 111 | 12.224069629545902 112 | >>> haversine(-20, 50, 30, 70) 113 | 53.57930271469817 114 | """ 115 | # convert decimal degrees to radians 116 | lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2]) 117 | 118 | # haversine formula 119 | dlon = lon2 - lon1 120 | dlat = lat2 - lat1 121 | delta = ( 122 | math.sin(dlat / 2.0) ** 2.0 123 | + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2.0) ** 2.0 124 | ) 125 | return 2.0 * math.degrees(math.asin(math.sqrt(delta))) 126 | 127 | 128 | def point_inside_circular( 129 | lat1: float, 130 | lon1: float, 131 | lat2: float, 132 | lon2: float, 133 | minradius: float | None = None, 134 | maxradius: float | None = None, 135 | ) -> bool: 136 | """ 137 | Check if a point is inside a circular region. 138 | 139 | Parameters 140 | ---------- 141 | lat1 142 | Latitude of the point. 143 | lon1 144 | Longitude of the point. 145 | lat2 146 | Latitude of center of the circular region. 147 | lon2 148 | Longitude of center of the circular region. 149 | minradius 150 | Minimum radius in degrees of the circular region. 151 | maxradius 152 | Maximum radius in degrees of the circular region. 153 | 154 | Returns 155 | ------- 156 | bool 157 | True if the point is inside the circular region. 158 | 159 | Examples 160 | -------- 161 | >>> point_inside_circular(30, 50, 30, 52, 0, 5) 162 | True 163 | """ 164 | radius = haversine(lat1, lon1, lat2, lon2) 165 | return not ( 166 | (minradius and radius < minradius) or (maxradius and radius > maxradius) 167 | ) 168 | 169 | 170 | def to_datetime(value: str | datetime | date) -> datetime: 171 | """ 172 | Convert a datetime from :class:`str` to :class:`datetime.datetime` in a hard way. 173 | 174 | Parameters 175 | ---------- 176 | value 177 | A :class:`datetime.datetime` object or a datetime string. 178 | 179 | Returns 180 | ------- 181 | datetime 182 | A datetime as :class:`datetime.datetime`. 183 | 184 | Examples 185 | -------- 186 | >>> to_datetime("201001010000") 187 | datetime.datetime(2010, 1, 1, 0, 0) 188 | >>> to_datetime("2010-01-01T03:45") 189 | datetime.datetime(2010, 1, 1, 3, 45) 190 | """ 191 | # is datetime 192 | if isinstance(value, datetime): 193 | return value 194 | # is date 195 | if isinstance(value, date): 196 | return datetime.combine(value, datetime.min.time()) 197 | 198 | # is a string 199 | for char in ["T", "-", ":", ",", "_"]: 200 | value = value.replace(char, " ") 201 | 202 | parts = value.split(" ") 203 | strfmt = "%Y%m%d%H%M%S" 204 | if len(parts) == 1: 205 | if len(value) == 8: 206 | strfmt = "%Y%m%d" 207 | elif len(value) == 12: 208 | strfmt = "%Y%m%d%H%M" 209 | elif len(value) == 14: 210 | strfmt = "%Y%m%d%H%M%S" 211 | elif len(value) > 14: 212 | strfmt = "%Y%m%d%H%M%S.%f" 213 | elif len(parts) == 3: 214 | strfmt = "%Y %m %d" 215 | elif len(parts) == 5: 216 | strfmt = "%Y %m %d %H %M" 217 | elif len(parts) == 6: 218 | strfmt = "%Y %m %d %H %M %S.%f" if "." in value else "%Y %m %d %H %M %S" 219 | 220 | return datetime.strptime(value, strfmt) 221 | 222 | 223 | def check_cmd_exists(cmd: str) -> bool: 224 | """ 225 | Check if a command exists in PATH and is executable. 226 | 227 | Parameters 228 | ---------- 229 | cmd 230 | Name of the command. 231 | 232 | Returns 233 | ------- 234 | bool 235 | True is the command exists in PATH is executable. 236 | """ 237 | fullpath = shutil.which(cmd) 238 | if fullpath: 239 | print(f"{cmd}: Full path is {fullpath}.") 240 | else: 241 | print(f"{cmd}: Not found in PATH or isn't executable.") 242 | return bool(fullpath) 243 | 244 | 245 | def check_package_release() -> bool: 246 | """ 247 | Check whether HinetPy has a new release. 248 | 249 | Returns 250 | ------- 251 | bool 252 | True if HinetPy has a new release. 253 | """ 254 | res = requests.get("https://pypi.org/pypi/HinetPy/json", timeout=30) 255 | if res.status_code != 200: 256 | raise requests.HTTPError("Error in connecting to PyPI.") 257 | latest_release = res.json()["info"]["version"] 258 | 259 | current_version = f'v{version("HinetPy")}' 260 | if Version(latest_release) > Version(current_version): 261 | print( 262 | f"HinetPy v{latest_release} is released. " 263 | "See https://pypi.org/project/HinetPy/ for details." 264 | ) 265 | return True 266 | 267 | print(f"You're using the latest version (v{current_version}).") 268 | return False 269 | -------------------------------------------------------------------------------- /HinetPy/win32.py: -------------------------------------------------------------------------------- 1 | """ 2 | Process seismic waveform data in win32 format. 3 | """ 4 | 5 | import glob 6 | import logging 7 | import os 8 | import shutil 9 | import subprocess 10 | import tempfile 11 | from fnmatch import fnmatch 12 | from multiprocessing import Pool 13 | from subprocess import DEVNULL, PIPE, Popen 14 | 15 | from .channel import Channel 16 | 17 | # Setup the logger 18 | FORMAT = "[%(asctime)s] %(levelname)s: %(message)s" 19 | logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt="%Y-%m-%d %H:%M:%S") 20 | logger = logging.getLogger(__name__) 21 | 22 | 23 | def extract_sac( 24 | data, 25 | ctable, 26 | suffix="SAC", 27 | outdir=".", 28 | pmax=8640000, 29 | filter_by_id=None, 30 | filter_by_name=None, 31 | filter_by_component=None, 32 | with_sacpz=False, 33 | processes=None, 34 | ): 35 | """ 36 | Extract data as SAC format files. 37 | 38 | This function calls the ``win2sac_32`` command, available in the Hi-net win32tools 39 | package, to convert data files from win32 format to SAC fomrat. It can also extract 40 | the channel information as SAC polezero files. 41 | 42 | Note that the ``win2sac_32`` command always remove the instrument sensitivity from 43 | waveform data, and multiply the data by 1.0e9. Thus, the extracted SAC files are not 44 | in digital counts, but velocity in nm/s, or acceleration in nm/s/s. Due to the same 45 | reason, the extracted SAC polezero files does not keep the sensitivity in the 46 | "CONSTANT" of SAC polezero files. 47 | 48 | Parameters 49 | ---------- 50 | data: str 51 | win32 file to be processed. 52 | ctable: str 53 | Channel table file. 54 | suffix: str 55 | Suffix of output SAC files. Defaults to ``SAC``. 56 | outdir: str 57 | Output directory. Defaults to current directory. 58 | pmax: int 59 | Maximum number of data points for one channel. Defaults to 8640000. If one 60 | channel has more than 8640000 data points (i.e., longer than one day for a 61 | 100 Hz sampling rate), you MUST increase ``pmax``. 62 | filter_by_id: list or str 63 | Filter channels by ID. It can be a list of IDs or a wildcard. 64 | filter_by_name: list or str 65 | Filter channels by name. It can be a list of names or a wildcard. 66 | filter_by_component: list or str 67 | Filter channels by component. It can be a list of component names or a wildcard. 68 | with_sacpz: bool 69 | Aslo extract SAC PZ files. By default, the suffix is ``.SAC_PZ`` and the channel 70 | sensitivity is not kept in the "CONSTANT". 71 | processes: None or int 72 | Number of processes to speed up data extraction parallelly. ``None`` means using 73 | all CPUs. 74 | 75 | .. deprecated:: 0.7.0 76 | 77 | Parameter ``with_pz`` is deprecated. Use ``with_sacpz`` instead. 78 | 79 | Examples 80 | -------- 81 | Extract all channels with default settings: 82 | 83 | >>> extract_sac("0101_201001010000_5.cnt", "0101_20100101.ch") 84 | 85 | Extract all channels with a specified suffix and output directory: 86 | 87 | >>> extract_sac( 88 | ... "0101_201001010000_5.cnt", 89 | ... "0101_20100101.ch", 90 | ... suffix="", 91 | ... outdir="20100101000", 92 | ... ) 93 | 94 | Extract only specified channels: 95 | 96 | >>> extract_sac( 97 | ... "0101_201001010000_5.cnt", 98 | ... "0101_20100101.ch", 99 | ... filter_by_name="N.NA*", 100 | ... filter_by_component="[NE]", 101 | ... ) 102 | """ 103 | if data is None or ctable is None: 104 | logger.error("data or ctable is `None'. Data requests may fail. Skipped.") 105 | return 106 | 107 | channels = read_ctable(ctable) 108 | logger.info("%s channels found in %s.", len(channels), ctable) 109 | if filter_by_id or filter_by_name or filter_by_component: 110 | channels = _filter_channels( 111 | channels, filter_by_id, filter_by_name, filter_by_component 112 | ) 113 | logger.info("%s channels to be extracted.", len(channels)) 114 | 115 | if not os.path.exists(outdir): 116 | os.makedirs(outdir, exist_ok=True) 117 | 118 | with Pool(processes=processes) as pool: 119 | with tempfile.NamedTemporaryFile() as ftmp: 120 | _write_winprm(ctable, ftmp.name) 121 | sacfiles = pool.starmap( 122 | _extract_channel_sac, 123 | [(data, ch, suffix, outdir, ftmp.name, pmax) for ch in channels], 124 | ) 125 | logger.info( 126 | "%s SAC data successfully extracted.", 127 | len(sacfiles) - sacfiles.count(None), 128 | ) 129 | 130 | if with_sacpz: 131 | # "SAC_PZ" here is hardcoded. 132 | pzfiles = pool.starmap( 133 | _extract_channel_sacpz, [(ch, "SAC_PZ", outdir) for ch in channels] 134 | ) 135 | logger.info( 136 | "%s SAC PZ files successfully extracted.", 137 | len(pzfiles) - pzfiles.count(None), 138 | ) 139 | 140 | 141 | def extract_sacpz( 142 | ctable, 143 | suffix="SAC_PZ", 144 | outdir=".", 145 | keep_sensitivity=False, 146 | filter_by_chid=None, 147 | filter_by_name=None, 148 | filter_by_component=None, 149 | processes=None, 150 | ): 151 | """ 152 | Extract instrumental responses in SAC polezero format from a channel table. 153 | 154 | .. warning:: 155 | 156 | The function only works for Hi-net instrumental responses. 157 | 158 | RESP files of the F-net network can be downloaded from 159 | `F-net website `_. 160 | 161 | Parameters 162 | ---------- 163 | ctable: str 164 | Channel table file. 165 | suffix: str 166 | Suffix of SAC PZ files. Defaults to ``SAC_PZ``. 167 | outdir: str 168 | Output directory. Defaults to current directory. 169 | keep_sensitivity: bool 170 | The ``win2sac_32`` program automatically removes sensitivity from waveform data 171 | during the win32-to-SAC format conversion. So the generated polezero file should 172 | omit the sensitivity. 173 | filter_by_id: list or str 174 | Filter channels by ID. It can be a list of IDs or a wildcard. 175 | filter_by_name: list or str 176 | Filter channels by name. It can be a list of names or a wildcard. 177 | filter_by_component: list or str 178 | Filter channels by component. It can be a list of component names or a wildcard. 179 | processes: None or int 180 | Number of processes to speed up data extraction parallelly. ``None`` means using 181 | all CPUs. 182 | 183 | Examples 184 | -------- 185 | Extract all channels with default settings: 186 | 187 | >>> extract_sacpz("0101_20100101.ch") 188 | 189 | Extract all channels with a specified suffix and output directory: 190 | 191 | >>> extract_sacpz("0101_20100101.ch", suffix="", outdir="20100101000") 192 | 193 | Extract only specified channels: 194 | 195 | >>> extract_sacpz( 196 | ... "0101_20100101.ch", filter_by_name="N.NA*", filter_by_component="[NE]" 197 | ... ) 198 | """ 199 | if ctable is None: 200 | logger.error("ctable is `None'. Data requests may fail. Skipped.") 201 | return 202 | 203 | channels = read_ctable(ctable) 204 | if filter_by_chid or filter_by_name or filter_by_component: 205 | channels = _filter_channels( 206 | channels, filter_by_chid, filter_by_name, filter_by_component 207 | ) 208 | if not os.path.exists(outdir): 209 | os.makedirs(outdir, exist_ok=True) 210 | 211 | with Pool(processes=processes) as pool: 212 | args = [(ch, suffix, outdir, keep_sensitivity) for ch in channels] 213 | pzfiles = pool.starmap(_extract_channel_sacpz, args) 214 | logger.info( 215 | "%s SAC PZ files successfully extracted.", 216 | len(pzfiles) - pzfiles.count(None), 217 | ) 218 | 219 | 220 | def extract_pz(ctable, **kwargs): 221 | """ 222 | Extract instrumental responses in SAC polezero format from a channel table. 223 | 224 | .. deprecated:: 0.7.0 225 | 226 | :meth:`~HinetPy.win32.extract_pz` is deprecated. 227 | Use :meth:`~HinetPy.win32.extract_sacpz` instead. 228 | """ 229 | logger.warning("Function extract_pz() is deprecated. Use extract_sacpz() instead.") 230 | return extract_sacpz(ctable, **kwargs) 231 | 232 | 233 | def read_ctable(ctable): 234 | """ 235 | Read a channel table file. 236 | 237 | Parameters 238 | ---------- 239 | ctable: str 240 | Channle table file. 241 | 242 | Returns 243 | ------- 244 | list 245 | List of :class:`~HinetPy.win32.Channel`. 246 | """ 247 | channels = [] 248 | with open(ctable, encoding="utf8") as fct: 249 | for line in fct: 250 | # skip blank lines and comment lines 251 | if not line.strip() or line.strip().startswith("#"): 252 | continue 253 | items = line.split() 254 | try: 255 | channels.append( 256 | Channel( 257 | id=items[0], 258 | name=items[3], 259 | component=items[4], 260 | latitude=items[13], 261 | longitude=items[14], 262 | unit=items[8], 263 | gain=items[7], 264 | damping=items[10], 265 | period=items[9], 266 | preamplification=items[11], 267 | lsb_value=items[12], 268 | ) 269 | ) 270 | except ValueError as err: 271 | logger.warning( 272 | "Error in parsing channel information for %s.%s (%s). Skipped.", 273 | items[3], 274 | items[4], 275 | items[0], 276 | ) 277 | logger.warning("Original error message: %s", err) 278 | return channels 279 | 280 | 281 | def _filter_channels( 282 | channels, filter_by_id=None, filter_by_name=None, filter_by_component=None 283 | ): 284 | """ 285 | Filter channels by id, name and/or component. 286 | 287 | Parameters 288 | ---------- 289 | channels: :class:`~HinetPy.win32.Channel` 290 | List of channels to be filtered. 291 | filter_by_id: list or str 292 | Filter channels by ID. It can be a list of IDs or a wildcard. 293 | filter_by_name: list or str 294 | Filter channels by name. It can be a list of names or a wildcard. 295 | filter_by_component: list or str 296 | Filter channels by component. It can be a list of component names or a wildcard. 297 | """ 298 | 299 | def _filter(channels, key, filters): 300 | """ 301 | Filter channels by filters, which can be either a list or a wildcard. 302 | """ 303 | if isinstance(filters, list): # filter by list 304 | return [chn for chn in channels if getattr(chn, key) in filters] 305 | if isinstance(filters, str): # filter by wildcard 306 | return [chn for chn in channels if fnmatch(getattr(chn, key), filters)] 307 | raise ValueError("Only list and wildcard filter are supported.") 308 | 309 | for key, filter_by in ( 310 | ("id", filter_by_id), 311 | ("name", filter_by_name), 312 | ("component", filter_by_component), 313 | ): 314 | if filter_by is not None: 315 | channels = _filter(channels, key, filter_by) 316 | return channels 317 | 318 | 319 | def _write_winprm(ctable, prmfile="win.prm"): 320 | """ 321 | Write a four-line parameter file. 322 | """ 323 | with open(prmfile, "w", encoding="utf8") as fprm: 324 | fprm.write(f".\n{ctable}\n.\n.") 325 | 326 | 327 | def _extract_channel_sac( 328 | winfile, channel, suffix="SAC", outdir=".", prmfile="win.prm", pmax=8640000 329 | ): 330 | """ 331 | Extract one channel data from win32 file. 332 | 333 | Parameters 334 | ---------- 335 | winfile: str 336 | win32 file to be processed. 337 | channel: str 338 | Channel to be extracted. 339 | suffix: str 340 | SAC file suffix. 341 | outdir: str 342 | Output directory. 343 | prmfile: str 344 | win32 parameter file. 345 | pmax: int 346 | Maximum number of data points. 347 | 348 | Returns 349 | ------- 350 | str: 351 | The extracted SAC file name. 352 | """ 353 | 354 | cmd = [ 355 | "win2sac_32", 356 | winfile, 357 | channel.id, 358 | suffix, 359 | outdir, 360 | "-e", 361 | f"-p{prmfile}", 362 | f"-m{pmax}", 363 | ] 364 | with Popen(cmd, stdout=DEVNULL, stderr=PIPE) as proc: 365 | # check stderr output 366 | for line in proc.stderr.read().decode().split("\n"): 367 | if "The number of points is maximum over" in line: 368 | raise ValueError( 369 | "The number of data points is over maximum. Try to increase pmax." 370 | ) 371 | if f"Data for channel {channel.id} not existed" in line: 372 | # return None if no data avaiable 373 | logger.warning( 374 | "Data for %s.%s (%s) not exists. Skipped.", 375 | channel.name, 376 | channel.component, 377 | channel.id, 378 | ) 379 | return None 380 | 381 | filename = f"{channel.name}.{channel.component}.{suffix}" 382 | if outdir != ".": 383 | filename = os.path.join(outdir, filename) 384 | 385 | if os.path.exists(filename): # some channels have no data 386 | if suffix == "": # remove extra dot if suffix is empty 387 | shutil.move(filename, filename[:-1]) 388 | return filename[:-1] 389 | return filename 390 | return None 391 | 392 | 393 | def _extract_channel_sacpz( 394 | channel, suffix="SAC_PZ", outdir=".", keep_sensitivity=False 395 | ): 396 | """ 397 | Extract one SAC PZ file from a channel table file. 398 | 399 | Parameters 400 | ---------- 401 | channel: str 402 | Channel to be extracted. 403 | suffix: str 404 | Suffix of the SAC PZ file. 405 | outdir: str 406 | Output directory. 407 | keep_sensitivity: bool 408 | Keep sensitivity in the "CONSTANT" or not. 409 | 410 | Returns 411 | ------- 412 | str: 413 | The extracted SAC PZ file name. 414 | """ 415 | pzfile = f"{channel.name}.{channel.component}" 416 | if suffix: 417 | pzfile += "." + suffix 418 | pzfile = os.path.join(outdir, pzfile) 419 | channel.write_sacpz(pzfile, keep_sensitivity=keep_sensitivity) 420 | return pzfile 421 | 422 | 423 | def merge(data, total_data, force_sort=False): 424 | """ 425 | Merge multiple win32 files into one large win32 file. 426 | 427 | The function calls the ``catwin32`` command, available in the Hi-net win32tools 428 | package, to merge multiple win32 files into one large win32 file. 429 | 430 | By default, the ``catwin32`` command simply concatenates all files in the order they 431 | are passed. So the files must be sorted by their start time before being passed. If 432 | your files are named by starttime like ``201304040203.cnt``, you can use 433 | ``data=sorted(glob.glob("20130404*.cnt"))`` to pass the sorted list of files. 434 | Otherwise, you have to use ``force_sort=True``, forcing ``catwin32`` to sort all 435 | files by starttime before merging. However, the sorting process is very time 436 | consuming. Do NOT set ``force_sort=True`` unless necessary. 437 | 438 | Parameters 439 | ---------- 440 | data: list or str 441 | Win32 files to be merged. It can be a list of file names or a wildcard. 442 | total_data: str 443 | Filename of the ouput win32 file. 444 | force_sort: bool 445 | Sort all win32 files by starttime before merging. 446 | 447 | Examples 448 | -------- 449 | For win32 files that are named by starttime (e.g. ``201304040203.cnt``), sorting 450 | win32 files using Python's built-in :func:`sorted` function is preferred: 451 | 452 | >>> data = sorted(glob.glob("20130404*.cnt")) 453 | >>> merge(data, "outdir/final.cnt") 454 | 455 | If win32 files are randomly named, you should use ``force_sort=True`` to force 456 | ``catwin32`` to sort all data by time before merging. 457 | 458 | >>> data = ["001.cnt", "002.cnt", "003.cnt"] 459 | >>> merge(data, "final.cnt", force_sort=True) 460 | 461 | You can also use wildcard to specify the win32 files to be merged. The function will 462 | sort the matched files for you automatically. 463 | 464 | >>> merge("20130404*.cnt", "final.cnt") 465 | """ 466 | if isinstance(data, str): # wildcard support 467 | data = sorted(glob.glob(data)) 468 | if not data: 469 | raise FileNotFoundError("Files to be merged not found.\n") 470 | 471 | if os.path.dirname(total_data): 472 | os.makedirs(os.path.dirname(total_data), exist_ok=True) 473 | 474 | cmd = ["catwin32", "-o", total_data, *data] 475 | if force_sort: # add -s option to force sort 476 | cmd.append("-s") 477 | 478 | subprocess.call(cmd, stdout=DEVNULL, stderr=DEVNULL) 479 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2024 Dongdong Tian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | prune .github* 2 | prune doc* 3 | prune paper* 4 | prune tests* 5 | exclude .gitignore 6 | exclude CITATION.cff 7 | exclude Makefile 8 | exclude requirements.txt 9 | exclude requirements-dev.txt 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Build, test, docs, and clean 2 | help: 3 | @echo "Commands:" 4 | @echo "" 5 | @echo " install install in editable mode" 6 | @echo " test run the test suite and report coverage" 7 | @echo " doc build the documentation" 8 | @echo " format run ruff to automatically format the code" 9 | @echo " check run ruff to check code style and quality" 10 | @echo " typecheck run mypy for static type check" 11 | @echo " clean clean up build and generated files" 12 | @echo " dist-clean clean up egg-info files" 13 | @echo "" 14 | 15 | install: 16 | python -m pip install --no-deps -e . 17 | 18 | test: 19 | pytest tests/test_*.py 20 | 21 | doc: 22 | make -C docs docs 23 | 24 | format: 25 | ruff check --fix --exit-zero . 26 | ruff format . 27 | 28 | check: 29 | ruff check . 30 | ruff format --check . 31 | 32 | typecheck: 33 | mypy HinetPy 34 | 35 | clean: 36 | find . -name "*.pyc" -exec rm -v {} \; 37 | find . -name "*.mo" -exec rm -v {} \; 38 | rm -rvf build dist sdist */__pycache__ .eggs/ 39 | rm -rvf .cache .pytest_cache .coverage* coverage.xml .ruff_cache .mypy_cache 40 | rm -rvf testdir-* 41 | 42 | dist-clean: clean 43 | rm -rvf *.egg-info 44 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://github.com/seisman/HinetPy/actions/workflows/tests.yml/badge.svg 2 | :target: https://github.com/seisman/HinetPy/actions/workflows/tests.yml 3 | .. image:: https://codecov.io/gh/seisman/HinetPy/branch/main/graph/badge.svg 4 | :target: https://codecov.io/gh/seisman/HinetPy 5 | .. image:: https://img.shields.io/github/release/seisman/HinetPy.svg 6 | :target: https://github.com/seisman/HinetPy/releases 7 | .. image:: https://img.shields.io/pypi/v/HinetPy.svg 8 | :target: https://pypi.org/project/HinetPy/ 9 | .. image:: https://img.shields.io/pypi/pyversions/HinetPy.svg 10 | :target: https://pypi.org/project/HinetPy/ 11 | .. image:: https://img.shields.io/github/license/seisman/HinetPy.svg 12 | :target: https://github.com/seisman/HinetPy/blob/main/LICENSE 13 | .. image:: https://joss.theoj.org/papers/10.21105/joss.06840/status.svg 14 | :target: https://doi.org/10.21105/joss.06840 15 | .. image:: https://zenodo.org/badge/23509035.svg 16 | :target: https://zenodo.org/badge/latestdoi/23509035 17 | 18 | 19 | `NIED Hi-net `__ | 20 | `Source Code `__ | 21 | `Documentation `__ | 22 | `中文文档 `__ 23 | 24 | ---- 25 | 26 | .. placeholder-for-doc-index 27 | 28 | `HinetPy `_ is a Python package for accessing and 29 | processing seismic data from `NIED Hi-net `__. 30 | 31 | Key Features 32 | ============ 33 | 34 | - Facilitates easy access to NIED Hi-net seismic data, including continuous/event 35 | waveform data and event catalogs. 36 | - Supports multiple seismic networks (e.g., F-net, S-net, MeSO-net and more in addition 37 | to Hi-net) in Japan. 38 | - Selects a subset of stations based on geographical location or station name (Supports 39 | Hi-net, F-net, S-net and MeSO-net only). 40 | - Converts waveform data to SAC format and instrumental responses to SAC polezero files. 41 | - Speeds up the downloading and processing workflow via the use of multithreading. 42 | 43 | A simple example 44 | ================ 45 | 46 | Here is an example showing how to use HinetPy to request continuous waveform data from 47 | Hi-net, convert the data into SAC format, and extract instrumental responses as SAC 48 | polezero files. 49 | 50 | .. code-block:: python 51 | 52 | from HinetPy import Client, win32 53 | 54 | # You need a Hi-net account to access the data 55 | client = Client("username", "password") 56 | 57 | # Let's try to request 20-minute data of the Hi-net network (with an internal 58 | # network code of '0101') starting at 2010-01-01T00:00 (JST, GMT+0900) 59 | data, ctable = client.get_continuous_waveform("0101", "201001010000", 20) 60 | 61 | # The request and download process usually takes a few minutes 62 | # waiting for data request ... 63 | # waiting for data download ... 64 | 65 | # Now you can see the data and corresponding channel table in your working directory 66 | # waveform data (in win32 format) : 0101_201001010000_20.cnt 67 | # channel table (plaintext file) : 0101_20100101.ch 68 | 69 | # Let's convert data from win32 format to SAC format 70 | win32.extract_sac(data, ctable) 71 | 72 | # Let's extract instrument response as PZ files from the channel table file 73 | win32.extract_sacpz(ctable) 74 | 75 | # Now you can see several SAC and SAC_PZ files in your working directory 76 | 77 | # N.NGUH.E.SAC N.NGUH.U.SAC N.NNMH.N.SAC 78 | # N.NGUH.N.SAC N.NNMH.E.SAC N.NNMH.U.SAC 79 | # ... 80 | # N.NGUH.E.SAC_PZ N.NGUH.U.SAC_PZ N.NNMH.N.SAC_PZ 81 | # N.NGUH.N.SAC_PZ N.NNMH.E.SAC_PZ N.NNMH.U.SAC_PZ 82 | # ... 83 | 84 | Citation 85 | ======== 86 | 87 | If you find this package useful, please consider citing the package in either of the 88 | following ways: 89 | 90 | **Cite the HinetPy paper (preferred)** 91 | 92 | A formal paper is published on `The Journal of Open Source Software `__ 93 | since HinetPy v0.9.0. This is the **preferred** way for citation. 94 | 95 | Tian, D. (2024). HinetPy: A Python package for accessing and processing NIED Hi-net seismic data. 96 | Journal of Open Source Software, 9(98), 6840. https://doi.org/10.21105/joss.06840 97 | 98 | **Cite a specific HinetPy version** 99 | 100 | If you'd like to cite a specific HinetPy version, you can visit 101 | `Zenodo `__, choose the version you want to cite, 102 | and cite like this: 103 | 104 | Tian, D. (20XX). HinetPy: A Python package for accessing and processing NIED Hi-net seismic data (X.X.X). 105 | Zenodo. https://doi.org/10.5281/zenodo.xxxxxxxx 106 | 107 | Contributing 108 | ============ 109 | 110 | Feedback and contributions are welcome! Please feel free to open an issue or pull 111 | request if you have any suggestions or would like to contribute a feature. 112 | For additional information or specific questions, please open an issue directly. 113 | 114 | License 115 | ======= 116 | 117 | This project is licensed under the terms of the MIT license. 118 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | 22 | translation: gettext 23 | sphinx-intl update -p _build/gettext -l zh_CN 24 | 25 | html-zh_CN: 26 | @echo "Building Chinese version HTML files." 27 | sphinx-intl build 28 | $(SPHINXBUILD) -b html -d $(BUILDDIR)/doctrees \ 29 | $(SPHINXOPTS) -D language='zh_CN' \ 30 | $(SOURCEDIR) $(BUILDDIR)/html/zh_CN 31 | 32 | docs: html html-zh_CN 33 | @echo "Building HTML files" 34 | -------------------------------------------------------------------------------- /docs/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {# Import the theme's layout. #} 2 | {% extends "!layout.html" %} 3 | 4 | {% block menu %} 5 | {{ super() }} 6 | 7 | {% if menu_links %} 8 |

9 | Links 10 |

11 |
    12 | {% for text, link in menu_links %} 13 |
  • {{ text }}
  • 14 | {% endfor %} 15 |
16 | {% endif %} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | API Reference 3 | ============= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | :caption: Modules: 8 | 9 | api/HinetPy.client.rst 10 | api/HinetPy.win32.rst 11 | api/HinetPy.channel.rst 12 | api/HinetPy.header.rst 13 | api/HinetPy.utils.rst 14 | -------------------------------------------------------------------------------- /docs/api/HinetPy.channel.rst: -------------------------------------------------------------------------------- 1 | HinetPy.channel module 2 | ---------------------- 3 | 4 | .. automodule:: HinetPy.channel 5 | :members: 6 | :undoc-members: 7 | -------------------------------------------------------------------------------- /docs/api/HinetPy.client.rst: -------------------------------------------------------------------------------- 1 | HinetPy.client module 2 | --------------------- 3 | 4 | .. autoclass:: HinetPy.client.Client 5 | :undoc-members: 6 | :inherited-members: 7 | :member-order: bysource 8 | 9 | .. autoclass:: HinetPy.client.Event 10 | :undoc-members: 11 | 12 | .. autoclass:: HinetPy.client.Station 13 | :undoc-members: 14 | -------------------------------------------------------------------------------- /docs/api/HinetPy.header.rst: -------------------------------------------------------------------------------- 1 | HinetPy.header module 2 | --------------------- 3 | 4 | .. automodule:: HinetPy.header 5 | 6 | .. autoclass:: HinetPy.header.Network 7 | -------------------------------------------------------------------------------- /docs/api/HinetPy.utils.rst: -------------------------------------------------------------------------------- 1 | HinetPy.utils module 2 | -------------------- 3 | 4 | .. automodule:: HinetPy.utils 5 | :members: 6 | :undoc-members: 7 | -------------------------------------------------------------------------------- /docs/api/HinetPy.win32.rst: -------------------------------------------------------------------------------- 1 | HinetPy.win32 module 2 | -------------------- 3 | 4 | .. automodule:: HinetPy.win32 5 | :members: 6 | :undoc-members: 7 | -------------------------------------------------------------------------------- /docs/appendix.rst: -------------------------------------------------------------------------------- 1 | Appendix 2 | ======== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | appendix/catwin32 8 | appendix/win2sac 9 | appendix/channeltable 10 | appendix/response 11 | -------------------------------------------------------------------------------- /docs/appendix/catwin32.rst: -------------------------------------------------------------------------------- 1 | catwin32 2 | ======== 3 | 4 | Merger of two or more data sets saved in WIN32 format. 5 | 6 | Usage 7 | ------ 8 | 9 | :: 10 | 11 | catwin32 File_1 File_2 ... File_n [-oOutFile | -o OutFile] [-s] [-h] > [OutFile] 12 | File_n : Input WIN32 file name (accept wildcard). 13 | -o OutFile : Output WIN32 file name. Defaults to stdout if -o is ommitted. 14 | -s : Sort by date and channel number. This option is time consuming. 15 | -h : This usage print. 16 | 17 | By default, ``catwin32`` will merge all input win32 files into one output 18 | win32 file, following the order they appear in arguments list. If the input 19 | files in arguments list is not sorted by date and ``-s`` option is not used, 20 | ``win2sac_32`` will fail to convert the output win32 format to SAC format, 21 | resulting an error ``The time is not sort.`` 22 | 23 | Two ways to solve this issue: 24 | 25 | 1. use ``-s`` option 26 | 2. make sure all the win32 files in arguments list are sorted by date 27 | 28 | The first way is safer, but time-consuming. The second way is prefered. 29 | You can use ``sorted(glob.glob("*.cnt"))`` in Python if the win32 files are 30 | named by time. 31 | 32 | Examples 33 | -------- 34 | 35 | Merge all win32 files matching ``20100101*.cnt`` into one win32 file:: 36 | 37 | catwin32 20100101*.cnt -o 0101_201001010000_5.cnt 38 | 39 | Merge several win32 files into one win32 file, sorted by date and 40 | channal number:: 41 | 42 | catwin32 1.cnt 2.cnt 3.cnt -o total.cnt -s 43 | -------------------------------------------------------------------------------- /docs/appendix/channeltable.rst: -------------------------------------------------------------------------------- 1 | Channel Table file 2 | ================== 3 | 4 | Channel table file contains important information about channels. 5 | 6 | Below is an example of one channel in channel table file:: 7 | 8 | 6033 1 0 N.AAKH U 6 27 175.60 m/s 1.00 0.70 0 1.023e-07 36.3726 137.9203 483 0 0 Azuminoakashina 9 | 10 | - [1]: Hexadecimal channel number (2-byte) 11 | - [2]: Recording flag 12 | - [3]: Delay time on a circuit (ms) 13 | - [4]: Station code 14 | - [5]: Motion component code 15 | - [6]: Reduction ratio of monitoring waveform (expressed as the integer exponent of a power of 2) 16 | - [7]: Quantization bit rate in A/D conversion 17 | - [8]: Sensor sensitivity (V/unit of input, where unit of input is provided in column [9]) 18 | - [9]: Unit of input. Use MKS system: "m" for displacement, "m/s" for velocity, and "m/s/s" for acceleration. 19 | - [10]: Natural period of the seismometer (s) 20 | - [11]: Damping constant of the sensor 21 | - [12]: Amplification factor applied to sensor output prior to A/D conversion (dB) 22 | - [13]: Quantization width in A/D conversion (V), a.k.a. LSB value 23 | - [14]: Station latitude (degrees). A positive value indicates North latitude. 24 | - [15]: Station longitude (degrees). A positive value indicates East longitude. 25 | - [16]: Station height (m) 26 | - [17]: Station correction for P-wave (s) 27 | - [18]: Station correction for S-wave (s) 28 | - [19]: Station name (Optional) 29 | -------------------------------------------------------------------------------- /docs/appendix/response.rst: -------------------------------------------------------------------------------- 1 | Instrumental Response 2 | ===================== 3 | 4 | Input 5 | ----- 6 | 7 | The unit of Hi-net input is determined by column [9], ususally ``m/s``. 8 | 9 | Analog Stage 10 | ------------ 11 | 12 | The moving coil velocity type seismometer is used in Hi-net and 13 | its transfer function in the Laplace domain is given as: 14 | 15 | .. math:: 16 | 17 | \frac{Gs^2}{s^2 + 2hws + w^2} 18 | 19 | where, 20 | 21 | - :math:`G`: gain factor, given as column [8] in ``V/unit_of_input`` 22 | - :math:`h`: damping constant, given as column [11] 23 | - :math:`w`: natural angular frequency, given as column [10] 24 | 25 | Roots of the numerator and the denominator correspond to the 26 | zeros and the poles, respectively, and the A0 normalization factor 27 | is the inverse of the absolute value of the 28 | above equation except G at the normalization frequency (:math:`f_n`). 29 | The normalization frequency of Hi-net seismometer is always 20 Hz. 30 | 31 | It's easy to know that the instrumental response has two poles and two zeros. 32 | It's also easy to calculate A0, with :math:`s=i*2*\pi*f_n`. 33 | 34 | Preamplification 35 | ---------------- 36 | 37 | The sensor ouput is amplified prior to A/D conversion. 38 | The amplification factor is determined by column [12] in dB. 39 | 40 | According to the definition of decibel of field quantities: 41 | 42 | .. math:: 43 | 44 | L_{F}=20\log _{10}\left({\frac {F}{F_{0}}}\right)\!~\mathrm {dB} . 45 | 46 | Thus, the "sensitivity" in this stage is :math:`10^{\frac{[12]}{20}}` . 47 | 48 | Analog-Digital Conversion 49 | ------------------------- 50 | 51 | The gain in this stage is given by :math:`\frac{1}{[13]}`, in ``counts/V``. 52 | 53 | Digital Stage 54 | ------------- 55 | 56 | The gain in this stage is 1.0, according to the three RESP files provided 57 | on Hi-net website. 58 | 59 | Summary 60 | ------- 61 | 62 | The total sensitivity is: 63 | 64 | .. math:: 65 | 66 | G = \frac{[8]*10^{\frac{[12]}{20}}}{[13]} 67 | 68 | The ``CONSTANT`` in SAC PZ file should be: 69 | 70 | .. math:: 71 | 72 | CONSTANT = A0 * G = A0 * \frac{[8]*10^{\frac{[12]}{20}}}{[13]} 73 | 74 | .. important:: 75 | 76 | HinetPy uses win2sac_32 to do the conversion from win32 to SAC format. 77 | win2sac_32 always remove total sensitivity (G) from waveform and multiply 78 | by 1.0e9 to convert unit from meter to nanometer. 79 | 80 | Thus, the extracted SAC files are velocity in nm/s or acceleration in nm/s/s. 81 | The total sensivitity G is also omitted when generating PZ files. 82 | 83 | Q&A 84 | --- 85 | 86 | My question: 87 | 88 | Hi, 89 | 90 | I am using Hi-net data and am confused with the instrumental response 91 | even after I have looked through all pages of Hi-net website. 92 | 93 | In the page of 'For Registered Users' -> 'Response of Observation Equipment', 94 | only three RESP files are given. It seems that I have to rewrite a new RESP 95 | or SAC_PZ file for each channel. 96 | 97 | So I have to confirm that I understand details of response, which are very 98 | important for correct data processing. 99 | 100 | 1. Do all channels have the same zeroes and poles? 101 | 2. At line 19, do all channels have the same A0 Normalization factor (0.999953)? 102 | 3. In the FAQ Q08, one equation is given to convert the A/D value from an WIN32 103 | file to the corresponding physical quantity. It is 104 | 105 | v = I * [13] / ([8] * 10 ^ ([12] / 20 ) ) 106 | 107 | If I want to generate a SAC PZ file, the CONSTANT will be 108 | 109 | CONSTANT = [8]*10^([12]/20) / [13] * A0 ? 110 | 111 | Answer from Hi-net: 112 | 113 | In the "Response of Observation Equipment" page, sample RESP files are 114 | provided and you need to modify them according to your purposes, as you 115 | wrote. The explanation in this page assumes that the parameters of the 116 | seismometer other than the gain factor do not change. Strictly speaking, 117 | the zeros, the poles, and the A0 normalization factor can change 118 | depending on the parameters of the seismometer. The moving coil velocity 119 | type seismometer is used in Hi-net and its transfer function in the 120 | Laplace domain is given as: 121 | 122 | Gs^2/(s^2 + 2hws + w^2) 123 | 124 | where G, h and w are the gain factor, the damping constant, and the 125 | natural angular frequency, respectively. Roots of the numerator and the 126 | denominator correspond to the zeros and the poles, respectively, and the 127 | A0 normalization factor is the inverse of the absolute value of the 128 | above equation except G at the normalization frequency. Detailed 129 | explanation about this type of seismometer is available in many 130 | literature, such as, 131 | 132 | Scherbaum, F., Of Poles and Zeros: Fundamentals of Digital Seismology, 133 | Kluwer Academic Publishers, 1996. 134 | #see chapter 4 135 | 136 | The gain factor, the damping constant, and the natural period are 137 | provided in the channels table file as explained in the Q&A08. 138 | Note that the gain factor is measured at its natural frequency. 139 | http://www.hinet.bosai.go.jp/faq/?LANG=en#Q08 140 | 141 | Please read the SEED manual about further details and SAC manual about 142 | SAC PZ file. 143 | 144 | - SEED: http://www.fdsn.org/publications.htm 145 | - SAC: http://www.iris.edu/files/sac-manual/ 146 | 147 | Sincerely, 148 | 149 | .. seealso:: 150 | 151 | - `Hi-net FAQ 08 `_ 152 | - `Response of Observation Equipment `_ 153 | -------------------------------------------------------------------------------- /docs/appendix/win2sac.rst: -------------------------------------------------------------------------------- 1 | win2sac 2 | ======= 3 | 4 | Data converter from WIN32 format to SAC format. It also supports BINARY/ASCII 5 | outputs. 6 | 7 | Usage 8 | ----- 9 | 10 | :: 11 | 12 | win2sac_32 winfile ch_no sacfile [outdir] [-p(prmfile)] 13 | [-Y] [-e] [-b[BIN]] [-a[ASC]] [-r(RATIO)] [-m(PMAX)] 14 | 15 | winfile: 16 | **one** win32 file to be converted. 17 | ch_no: 18 | channle numbers to be extracted. It can be: 19 | 20 | - a channel number (e.g. ``3345``) 21 | - a list of channel numbers, separated by commas (e.g. ``3345,3f65,4f75``) 22 | - a file contains channel numbers, see details below 23 | sacfile 24 | extension of output SAC files 25 | outdir 26 | output directory. Default is current directory if not specified 27 | or is ``-``. The output directory must exist. 28 | ``-p(prmfile)``: 29 | specify paramerter file. Default name is ``win.prm``. See details below. 30 | ``-Y`` 31 | use wild channel code. organization id + network id + channle id. 32 | ``-e`` 33 | specify SAC/BIN output to use endian of current machine. Defaults to use big endian. 34 | ``-b[BIN]`` 35 | extension of BIN format. Defaults to ``bin``. 36 | ``-a[ASC]`` 37 | extension of ASC format. Defaults to ``asc``. 38 | ``-r(RATIO)`` 39 | the ratio to multiply for BIN/ASC format. Defaults to 1.0. 40 | ``-m(PMAX)`` 41 | maximum number of data points. Defaults to ``2000000``. If you data has 42 | more data points, you must increase this value. 43 | 44 | Examples 45 | -------- 46 | 47 | :: 48 | 49 | win2sac_32 2000082404000101VM.cnt 4c55,4c65 SAC DATA -e > junk.log 50 | 51 | Notes 52 | ----- 53 | 54 | Output Unit 55 | ~~~~~~~~~~~ 56 | 57 | .. important:: 58 | 59 | The SAC files extracted by ``win2sac_32`` are always in physical quality, 60 | not in digital counts. 61 | 62 | The raw data saved in win32 format is in digital counts. When extracting data 63 | from win32 format, ``win2sac_32`` always convert digital counts to the 64 | corresponding physical quantity by remove sensitivity from waveform data, 65 | and multiply by 1.0e9 to convert unit from meter to nanometer. 66 | 67 | The output SAC files are in ``nm/s``, ``nm/s/s`` or ``micro radian``. 68 | 69 | Filename Format 70 | ~~~~~~~~~~~~~~~ 71 | 72 | The default filename format is ``STATION.COMPONENT.EXTENSION`` 73 | (e.g. ``N.NABC.U.SAC``). You can only modify the extensions. 74 | 75 | Channel number file format 76 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 77 | 78 | You can save all channel numbers you want to extract into one file. 79 | 80 | #. line starts with ``#`` is comment line and skipped 81 | #. blank lines are skipped 82 | #. channel numbers can be separated by spaces, tabs, or commas 83 | #. each line can contain no more than 2000 characters 84 | 85 | Below is an example:: 86 | 87 | 6034,6035 88 | # 6036 # this line is ignored 89 | 6038 6039 90 | 91 | .. danger:: 92 | 93 | Using this feature may result in data loss, as ``win2sac_32`` will exit 94 | if data of any channel doesn't exist in the win32 file. 95 | 96 | If you still want to use this fearture, you can modify Line 386 of 97 | ``s4win2sacm.c`` from:: 98 | 99 | fprintf(stderr, "Data for channel %x not existed\n", sysch); 100 | iRet = 1; 101 | 102 | to:: 103 | 104 | fprintf(stderr, "Data for channel %x not existed\n", sysch); 105 | 106 | Paramerter file 107 | ~~~~~~~~~~~~~~~ 108 | 109 | win32 system need a parameter file to run. This parameter file has many lines. 110 | However, ``win2sac_32`` only uses the 2nd and 4th lines, and ignores all other lines. 111 | 112 | An example of a four line parameter file:: 113 | 114 | . 115 | 0101_20100101.ch 116 | . 117 | . 118 | 119 | The 2nd line is the name of channle table file. ``win2sac_32`` need to read 120 | this file to extract waveform of specified channels. 121 | 122 | The 4th line is the path of pick files. It's useless for most cases. 123 | 124 | Component 125 | ~~~~~~~~~ 126 | 127 | The component information is written to SAC header variables ``CPMAZ`` and 128 | ``CMPINC``. 129 | 130 | - U/Z: CMPAZ = 0.0, CMPINC = 0.0 131 | - N/X: CMPAZ = 0.0, CMPINC = 90.0 132 | - E/Y: CMPAZ = 90.0, CMPINC = 90.0 133 | - Other: CMPAZ = 0.0, CMPINC = 0.0 134 | 135 | .. note:: 136 | 137 | Azimuths of sensors are **NOT** accurate. 138 | 139 | See https://hinetwww11.bosai.go.jp/auth/direc/?LANG=en for details. 140 | 141 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.10.0 (2024-11-21) 5 | ------------------- 6 | 7 | **Improved support for MeSO-net** 8 | 9 | MeSO-net has two network codes for different time periods: 10 | 11 | - ``0131`` for data after 20170401 12 | - ``0231`` for data 20080516-20170401 13 | 14 | In previous versions, you need to know the above information and choose the correct 15 | network code when requesting data before or after 20170401. In this new version, HinetPy 16 | can automatically switch the network code for you, depending on the data time you're 17 | requesting. Note that you will get an error if the time span you requested crosses the 18 | date 20170401. 19 | 20 | 21 | 0.9.1 (2024-07-12) 22 | ------------------ 23 | 24 | - ``get_selected_station``: Be more careful with checking the parsed values of stations 25 | 26 | 0.9.0 (2024-06-25) 27 | ------------------ 28 | 29 | - The HinetPy paper is published on JOSS. Check it at https://doi.org/10.21105/joss.06840. 30 | 31 | 0.8.3 (2024-06-05) 32 | ------------------ 33 | 34 | - Fix the "OSError: [Errno 18] Invalid cross-device link." for cross-system operations. 35 | 36 | 0.8.2 (2024-04-05) 37 | ------------------ 38 | 39 | - Add the updated solution for the "ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small" error 40 | 41 | 0.8.1 (2024-03-31) 42 | ------------------ 43 | 44 | - Minor changes to simplify some internal functions. 45 | 46 | 0.8.0 (2024-03-28) 47 | ------------------ 48 | 49 | - Support more newly added networks 50 | - Remove the hacking solution for SSL connection issue so it works well with urllib3 v2.x 51 | - Drop support for Python 3.7. 52 | 53 | 0.7.1 (2022-07-08) 54 | ------------------ 55 | 56 | - Fix bugs in ``get_event_waveform`` 57 | 58 | 0.7.0 (2022-07-01) 59 | ------------------ 60 | 61 | - Fix the incorrect maximum allowed time span for F-net (#65) 62 | - ``get_selected_stations`` now returns a list of stations with station metadata information (#36) 63 | - Refactor the ``_channel2pz()`` and ``_write_pz()`` functions to ``Channel.write_sacpz()`` 64 | - Refactor the ``_get_channels`` function to ``win32.read_ctable()`` 65 | - The ``win32.extrac_sacpz`` function now supports parallel data processing 66 | - The ``with_pz`` parameter in ``win32.extract_sac()`` is renamed to ``with_sacpz`` 67 | - The ``win32.extrac_pz()`` function is renamed to ``win32.extract_sacpz()`` 68 | - Move the function ``Client.check_cmd_exists()`` to ``utils.check_cmd_exists()`` 69 | - Move the function ``Client.check_package_release()`` to ``utils.check_package_release()`` 70 | - Fix the "ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small" error 71 | 72 | 0.6.9 (2021-05-20) 73 | ------------------ 74 | 75 | - Check invalid ``stations`` parameter type for ``Client.select_stations()`` 76 | 77 | 0.6.8 (2021-03-11) 78 | ------------------ 79 | 80 | - include_unknown_mag does not work in get_event_waveform() 81 | - Fail to download S-net data. 82 | 83 | 0.6.7 (2020-06-08) 84 | ------------------ 85 | 86 | - Improve code styles, tests and CI. 87 | 88 | 0.6.6 (2020-03-02) 89 | ------------------ 90 | 91 | - win32.extract_pz cannot filter channels by ID and name (#27) 92 | 93 | 0.6.5 (2019-12-06) 94 | ------------------ 95 | 96 | - Fix PZ files if damping constant is zero (#24) 97 | 98 | 0.6.4 (2019-08-23) 99 | ------------------ 100 | 101 | - Capture exception caused by incorrect channel information (#22) 102 | 103 | 0.6.3 (2019-06-13) 104 | ------------------ 105 | 106 | - Fix ``select_stations()`` (#19) 107 | - Rename ``string2datetime()`` to ``to_datetime()`` 108 | 109 | 0.6.2 (2019-05-06) 110 | ------------------ 111 | 112 | - Fix download focal mechanism catalog issue (#18). 113 | 114 | 0.6.1 (2019-02-20) 115 | ------------------ 116 | 117 | - Fix selecting events in a rectangular region. 118 | 119 | 0.6.0 (2019-02-19) 120 | ------------------ 121 | 122 | - Support request event waveform data (#16). 123 | - ``get_waveform()`` is renamed to ``get_continuous_waveform()``. 124 | 125 | 0.5.2 (2019-02-19) 126 | ------------------ 127 | 128 | - Fix selecting stations in a rectangular region (#17). 129 | 130 | 0.5.1 (2018-12-08) 131 | ------------------ 132 | 133 | - Fix typo from longtitude to longitude. 134 | 135 | 0.5.0 (2018-11-21) 136 | ------------------ 137 | 138 | - Fix issues of wrong CONSTANT in SAC polezero file (#8). 139 | - Fix login failure issue with password longer than 12 characters (#13). 140 | 141 | 0.4.8 (2018-10-04) 142 | ------------------ 143 | 144 | - ``get_station_list()``: must specify a network code; support S-net and MeSO-net. 145 | - ``select_stations()``: support S-net and MeSO-net 146 | 147 | 0.4.7 (2018-10-04) 148 | ------------------ 149 | 150 | - Support S-net and MeSO-net (#9 and #10) 151 | - Fix an issue when channel table contains blank lines 152 | 153 | 0.4.6 (2018-03-20) 154 | ------------------ 155 | 156 | - Fix ``Too many open files`` (#6) 157 | 158 | 0.4.5 (2018-03-07) 159 | ------------------ 160 | 161 | - ``get_station_list()``: return a list of stations 162 | - ``select_stations()``: support selecting stations in a box or circular region 163 | 164 | 0.4.4 (2017-11-30) 165 | ------------------ 166 | 167 | - Fix a technical issue related to packaging 168 | 169 | 0.4.3 (2017-11-30) 170 | ------------------ 171 | 172 | - Add Chinese documentation 173 | 174 | 0.4.2 (2017-06-18) 175 | ------------------ 176 | 177 | - Fix a bug with requests>=2.17 178 | 179 | 0.4.1 (2017-06-18) 180 | ------------------ 181 | 182 | - remove tempfile after downloading. 183 | 184 | 0.4.0 (2017-04-01) 185 | ------------------ 186 | 187 | - ``win32.extract_sac()``: skip if data not exists 188 | - ``win32.extract_sac()``: support multiple processes to speedup, and no longer return values 189 | - ``Client.get_waveform()``: support multi-threads to speedup 190 | - Change ``Client.help()`` to ``Client.info()`` 191 | - ``Client.get_waveform()`` now can automatically set ``max_span`` 192 | - ``Client.get_*()`` now support startime in different string formats 193 | 194 | 0.3.3 (2017-03-17) 195 | ------------------ 196 | 197 | - Change ``network`` to ``NETWORK`` in ``header.py`` 198 | - Add wildcard support to ``win32.merge()`` 199 | - Change ``Client.check_module_release()`` to ``Client.check_package_release()`` 200 | - Support output filename with deep directory 201 | - Always sort cnt files to avoid merge error 202 | - Set ``pmax`` to 8640000 by default 203 | - Fix typos 204 | 205 | 0.3.2 (2017-03-12) 206 | ------------------ 207 | 208 | - Fix another technical issue related to pypi 209 | 210 | 0.3.1 (2017-03-12) 211 | ------------------ 212 | 213 | - Fix a technical issue related to pypi 214 | 215 | 0.3.0 (2017-03-12) 216 | ------------------ 217 | 218 | - Rewritten as a Python package 219 | 220 | 0.2.0 (2016-08-24) 221 | ------------------ 222 | 223 | - Some small fixes and improvements 224 | 225 | 0.1.0 (2016-08-04) 226 | ------------------ 227 | 228 | - First public release 229 | - ``HinetDoctor.py``: check dependencies 230 | - ``HinetContRequest.py``: request continuous data from Hi-net 231 | - ``StationSelector.py``: select Hi-net/F-net stations before requesting data 232 | - ``HinetJMARequest.py``: request JMA catalogs from Hi-net website 233 | - ``rdhinet.py``: convert WIN32 format to SAC format 234 | - ``ch2pz.py``: extract SAC PZ files from Hi-net channel table files 235 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | import datetime 17 | 18 | import HinetPy 19 | 20 | # -- Project information ----------------------------------------------------- 21 | year = datetime.date.today().year 22 | project = "HinetPy" 23 | author = "Dongdong Tian" 24 | copyright = f"2014-{year}, {author}" # noqa: A001 25 | 26 | # The full version, including alpha/beta/rc tags 27 | version = HinetPy.__version__ 28 | release = version 29 | 30 | 31 | # -- General configuration --------------------------------------------------- 32 | 33 | # Add any Sphinx extension module names here, as strings. They can be 34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 35 | # ones. 36 | extensions = [ 37 | "sphinx.ext.autodoc", 38 | "sphinx.ext.autosummary", 39 | "sphinx.ext.githubpages", 40 | "sphinx.ext.intersphinx", 41 | "sphinx.ext.napoleon", 42 | "sphinx_rtd_theme", 43 | ] 44 | 45 | # Add any paths that contain templates here, relative to this directory. 46 | templates_path = ["_templates"] 47 | 48 | # List of patterns, relative to source directory, that match files and 49 | # directories to ignore when looking for source files. 50 | # This pattern also affects html_static_path and html_extra_path. 51 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 52 | 53 | 54 | # -- Options for HTML output ------------------------------------------------- 55 | 56 | # The theme to use for HTML and HTML Help pages. See the documentation for 57 | # a list of builtin themes. 58 | # 59 | html_theme = "sphinx_rtd_theme" 60 | 61 | # Add any paths that contain custom static files (such as style sheets) here, 62 | # relative to this directory. They are copied after the builtin static files, 63 | # so a file named "default.css" will overwrite the builtin "default.css". 64 | # html_static_path = ['_static'] 65 | 66 | html_context = { 67 | "menu_links": [ 68 | ( 69 | ' Source Code', 70 | "https://github.com/seisman/HinetPy", 71 | ), 72 | ( 73 | ' NIED Hi-net', 74 | "https://www.hinet.bosai.go.jp/", 75 | ), 76 | ( 77 | ' Documentation', 78 | "https://seisman.github.io/HinetPy/", 79 | ), 80 | ( 81 | ' 中文文档', 82 | "https://seisman.github.io/HinetPy/zh_CN/", 83 | ), 84 | ] 85 | } 86 | 87 | # autodoc options 88 | autodoc_member_order = "bysource" 89 | autoclass_content = "both" 90 | napoleon_numpy_docstring = True 91 | napoleon_use_admonition_for_notes = True 92 | napoleon_use_admonition_for_examples = True 93 | napoleon_use_admonition_for_references = True 94 | 95 | # intersphinx configurations 96 | intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)} 97 | 98 | # Chinese translation 99 | locale_dirs = ["locale/"] # path is example but recommended. 100 | gettext_compact = False # optional. 101 | -------------------------------------------------------------------------------- /docs/examples.rst: -------------------------------------------------------------------------------- 1 | Examples 2 | ======== 3 | 4 | .. toctree:: 5 | 6 | examples/example1 7 | examples/example2 8 | 9 | -------------------------------------------------------------------------------- /docs/examples/events.csv: -------------------------------------------------------------------------------- 1 | #EventID | Time | Latitude | Longitude | Depth/km | Author | Catalog | Contributor | ContributorID | MagType | Magnitude | MagAuthor | EventLocationName 2 | 9993759|2017-01-22T04:30:22|-6.2145|155.1442|135.0|pt,us,at|NEIC PDE|us|us10007uph,pt17022050,at00ok5z6p|mww|7.9|us|SOLOMON ISLANDS 3 | 9993037|2017-01-19T23:04:21|-10.3433|161.318|36.0|pt,us,at|NEIC PDE|us|us10007u7n,at00ok1ura,pt17019050|mww|6.5|us|SOLOMON ISLANDS 4 | 9953968|2017-01-10T06:13:47|4.4634|122.575|612.71|at,us|NEIC PDE|us|us10007s9c,at00ojjvz0|Mww|7.3|us|CELEBES SEA 5 | 9951821|2017-01-03T21:52:30|-19.3542|176.058|12.0|at,us,pt|NEIC PDE|us|us10007pj6,at00oj84rf,pt17003051|Mww|6.9|us|SOUTH OF FIJI ISLANDS 6 | -------------------------------------------------------------------------------- /docs/examples/example1.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import os 3 | from datetime import datetime, timedelta 4 | 5 | from HinetPy import Client, win32 6 | 7 | client = Client("username", "password") 8 | with open("events.csv") as csvfile: 9 | reader = csv.DictReader(csvfile, delimiter="|") 10 | reader.fieldnames = [field.strip() for field in reader.fieldnames] 11 | for row in reader: # loop over events 12 | origin = datetime.strptime(row["Time"], "%Y-%m-%dT%H:%M:%S") 13 | starttime = origin + timedelta(hours=9) # deal with TimeZone issue 14 | outdir = origin.strftime("%Y%m%d%H%M") 15 | 16 | # skip if outdir already exists to avoid overwrite 17 | if os.path.exists(outdir): 18 | continue 19 | 20 | data, ctable = client.get_continuous_waveform( 21 | "0101", starttime, 20, outdir=outdir 22 | ) 23 | win32.extract_sac(data, ctable, outdir=outdir, with_sacpz=True) 24 | -------------------------------------------------------------------------------- /docs/examples/example1.rst: -------------------------------------------------------------------------------- 1 | Request continuous waveform data from CSV catalog 2 | ------------------------------------------------- 3 | 4 | This example shows how to request waveform data based on a catalog in CSV format. 5 | 6 | Below is an example catalog file in CSV format. 7 | The catalog is obtained from `IRIS web service `_. 8 | 9 | .. include:: events.csv 10 | :literal: 11 | 12 | Python script: 13 | 14 | .. literalinclude:: example1.py 15 | :language: python 16 | -------------------------------------------------------------------------------- /docs/examples/example2.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import timedelta 3 | 4 | from HinetPy import Client, win32 5 | from obspy import UTCDateTime 6 | from obspy.clients.fdsn import Client as fdsnClient 7 | 8 | fdsnclient = fdsnClient("IRIS") 9 | starttime = UTCDateTime("2005-01-01") 10 | endtime = UTCDateTime("2005-01-03") 11 | catalog = fdsnclient.get_events( 12 | starttime=starttime, endtime=endtime, minmagnitude=6, catalog="ISC" 13 | ) 14 | 15 | client = Client("username", "password") 16 | for event in catalog: # loop over events 17 | origin = event.origins[0].time.datetime 18 | starttime = origin + timedelta(hours=9) # deal with TimeZone issue 19 | outdir = origin.strftime("%Y%m%d%H%M") 20 | 21 | # skip if outdir already exists to avoid overwrite 22 | if os.path.exits(outdir): 23 | continue 24 | 25 | data, ctable = client.get_continuous_waveform("0101", starttime, 20, outdir=outdir) 26 | win32.extract_sac(data, ctable, outdir=outdir, with_sacpz=True) 27 | -------------------------------------------------------------------------------- /docs/examples/example2.rst: -------------------------------------------------------------------------------- 1 | Request continous waveform data from obspy Catalog 2 | -------------------------------------------------- 3 | 4 | .. literalinclude:: example2.py 5 | :language: python 6 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | HinetPy 2 | ======= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | 8 | installation 9 | tutorial 10 | examples 11 | api 12 | appendix 13 | changelog 14 | license 15 | 16 | .. include:: ../README.rst 17 | :start-after: placeholder-for-doc-index 18 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Prerequisites 5 | ------------- 6 | 7 | To use HinetPy, you need: 8 | 9 | - Python >= 3.8 10 | - win32tools provided by NIED Hi-net (see below for install instructions) 11 | - a Hi-net account (register on Hi-net website to get your user name and password) 12 | 13 | Install HinetPy 14 | --------------- 15 | 16 | To install the latest **release/stable** version:: 17 | 18 | python -m pip install HinetPy 19 | 20 | Or install the **developing/unstable** version:: 21 | 22 | git clone https://github.com/seisman/HinetPy 23 | cd HinetPy 24 | python -m pip install . 25 | 26 | If you want to uninstall HinetPy, just run:: 27 | 28 | python -m pip uninstall HinetPy 29 | 30 | Build win32tools 31 | ---------------- 32 | 33 | `win32tools`_ is a collection of tools provided by `NIED Hi-net`_ to process 34 | win32 format data. HinetPy needs the ``catwin32`` and ``win2sac_32`` commands 35 | to process the win32 data. 36 | 37 | Run the following commands to build win32tools:: 38 | 39 | tar -xvf win32tools.tar.gz 40 | cd win32tools/ 41 | make 42 | 43 | For macOS users, the above command may fail with an fatal error like this:: 44 | 45 | s4read_data.c:3:13: fatal error: 'malloc.h' file not found 46 | #include 47 | ^ 48 | 1 error generated. 49 | make[1]: *** [s4read_data.o] Error 1 50 | 51 | In this case, you should change ``#include `` to ``#include `` at 52 | line 3 of ``win2sac.src/s4read_data.c``. 53 | 54 | After successfully building win32tools, you need to make sure that ``catwin32`` 55 | and ``win2sac_32`` are in your PATH. You can simply run the following command 56 | to copy the two commands into your HOME's bin directory:: 57 | 58 | cp catwin32.src/catwin32 win2sac.src/win2sac_32 $HOME/bin/ 59 | 60 | .. _NIED Hi-net: https://www.hinet.bosai.go.jp/ 61 | .. _win32tools: https://hinetwww11.bosai.go.jp/auth/manual/dlDialogue.php?r=win32tools 62 | 63 | -------------------------------------------------------------------------------- /docs/license.rst: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | .. include:: ../LICENSE 5 | :literal: 6 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/api.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.4.0\n" 19 | 20 | #: ../../api.rst:3 21 | msgid "API Reference" 22 | msgstr "API参考" 23 | 24 | #: ../../api.rst:5 25 | msgid "Modules:" 26 | msgstr "模块:" 27 | 28 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/appendix.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.4.0\n" 19 | 20 | #: ../../appendix.rst:2 21 | msgid "Appendix" 22 | msgstr "附录" 23 | 24 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/appendix/catwin32.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2018-11-21 16:01-0500\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.6.0\n" 18 | 19 | #: ../../appendix/catwin32.rst:2 20 | msgid "catwin32" 21 | msgstr "" 22 | 23 | #: ../../appendix/catwin32.rst:4 24 | msgid "Merger of two or more data sets saved in WIN32 format." 25 | msgstr "合并两个或多个WIN32格式的数据。" 26 | 27 | #: ../../appendix/catwin32.rst:7 28 | msgid "Usage" 29 | msgstr "用法" 30 | 31 | #: ../../appendix/catwin32.rst:17 32 | msgid "" 33 | "By default, ``catwin32`` will merge all input win32 files into one output" 34 | " win32 file, following the order they appear in arguments list. If the " 35 | "input files in arguments list is not sorted by date and ``-s`` option is " 36 | "not used, ``win2sac_32`` will fail to convert the output win32 format to " 37 | "SAC format, resulting an error ``The time is not sort.``" 38 | msgstr "" 39 | "默认情况下, ``catwin32`` " 40 | "会将所有输入的win32文件按照它们在参数列表中出现的顺序合并到输出的win32文件中。如果参数列表中输入文件不是按照日期排序且没有使用 " 41 | "``-s`` 选项,则 ``win2sac_32`` 无法将输出的win32格式转换为SAC格式,并报错 ``The time is not " 42 | "sort.``。" 43 | 44 | #: ../../appendix/catwin32.rst:23 45 | msgid "Two ways to solve this issue:" 46 | msgstr "两个解决此问题的方法:" 47 | 48 | #: ../../appendix/catwin32.rst:25 49 | msgid "use ``-s`` option" 50 | msgstr "使用 ``-s`` 选项" 51 | 52 | #: ../../appendix/catwin32.rst:26 53 | msgid "make sure all the win32 files in arguments list are sorted by date" 54 | msgstr "确保参数列表中所有win32文件是按照日期排序的" 55 | 56 | #: ../../appendix/catwin32.rst:28 57 | msgid "" 58 | "The first way is safer, but time-consuming. The second way is prefered. " 59 | "You can use ``sorted(glob.glob(\"*.cnt\"))`` in Python if the win32 files" 60 | " are named by time." 61 | msgstr "" 62 | "第一种方法更安全但更耗时,因而倾向于采用第二种方式。如果win32文件是按照日期命名的,则在Python里可以使用 " 63 | "``sorted(glob.glob(\"*.cnt\"))`` 以保证输入文件是按照时间先后排序的。" 64 | 65 | #: ../../appendix/catwin32.rst:33 66 | msgid "Examples" 67 | msgstr "示例" 68 | 69 | #: ../../appendix/catwin32.rst:35 70 | msgid "Merge all win32 files matching ``20100101*.cnt`` into one win32 file::" 71 | msgstr "将所有文件名满足 ``20100101*.cnt`` 的文件合并到一个文件中::" 72 | 73 | #: ../../appendix/catwin32.rst:39 74 | msgid "" 75 | "Merge several win32 files into one win32 file, sorted by date and channal" 76 | " number::" 77 | msgstr "将多个win32文件合并到一个win32文件中,并强制按日期和通道号排序::" 78 | 79 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/appendix/channeltable.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.4.0\n" 19 | 20 | #: ../../appendix/channeltable.rst:2 21 | msgid "Channel Table file" 22 | msgstr "通道表文件" 23 | 24 | #: ../../appendix/channeltable.rst:4 25 | msgid "Channel table file contains important information about channels." 26 | msgstr "通道表文件中包含了通道的重要信息。" 27 | 28 | #: ../../appendix/channeltable.rst:6 29 | msgid "Below is an example of one channel in channel table file::" 30 | msgstr "下面是通道表中一个通道的信息::" 31 | 32 | #: ../../appendix/channeltable.rst:10 33 | msgid "[1]: Hexadecimal channel number (2-byte)" 34 | msgstr "[1]: 十六进制通道号(2字节)" 35 | 36 | #: ../../appendix/channeltable.rst:11 37 | msgid "[2]: Recording flag" 38 | msgstr "[2]: 台站记录标识" 39 | 40 | #: ../../appendix/channeltable.rst:12 41 | msgid "[3]: Delay time on a circuit (ms)" 42 | msgstr "[3]: 电路延迟时间 (ms)" 43 | 44 | #: ../../appendix/channeltable.rst:13 45 | msgid "[4]: Station code" 46 | msgstr "[4]: 台站代码" 47 | 48 | #: ../../appendix/channeltable.rst:14 49 | msgid "[5]: Motion component code" 50 | msgstr "[5]: 分量代码" 51 | 52 | #: ../../appendix/channeltable.rst:15 53 | msgid "" 54 | "[6]: Reduction ratio of monitoring waveform (expressed as the integer " 55 | "exponent of a power of 2)" 56 | msgstr "" 57 | 58 | #: ../../appendix/channeltable.rst:16 59 | msgid "[7]: Quantization bit rate in A/D conversion" 60 | msgstr "[7]: A/D转换过程中的量化比特率" 61 | 62 | #: ../../appendix/channeltable.rst:17 63 | msgid "" 64 | "[8]: Sensor sensitivity (V/unit of input, where unit of input is provided" 65 | " in column [9])" 66 | msgstr "[8]: 传感器的敏感度 (单位是伏特每输出单位,其中输入单位由 [9] 列指定" 67 | 68 | #: ../../appendix/channeltable.rst:18 69 | msgid "" 70 | "[9]: Unit of input. Use MKS system: \"m\" for displacement, \"m/s\" for " 71 | "velocity, and \"m/s/s\" for acceleration." 72 | msgstr "[9]: 输入单位。使用MKS系统: \"m\" 代表位移, \"m/s\" 代表速度, " 73 | " \"m/s/s\" 代表加速度。" 74 | 75 | #: ../../appendix/channeltable.rst:19 76 | msgid "[10]: Natural period of the seismometer (s)" 77 | msgstr "[10]: 地震仪的自然周期 (s)" 78 | 79 | #: ../../appendix/channeltable.rst:20 80 | msgid "[11]: Damping constant of the sensor" 81 | msgstr "[11]: 传感器的阻尼常数" 82 | 83 | #: ../../appendix/channeltable.rst:21 84 | msgid "" 85 | "[12]: Amplification factor applied to sensor output prior to A/D " 86 | "conversion (dB)" 87 | msgstr "[12]: 在A/D转换前传感器输出的放大因子 (dB)" 88 | 89 | #: ../../appendix/channeltable.rst:22 90 | msgid "[13]: Quantization width in A/D conversion (V), a.k.a. LSB value" 91 | msgstr "[13]: A/D转换过程中的量化宽度(V),即LSB值" 92 | 93 | #: ../../appendix/channeltable.rst:23 94 | msgid "" 95 | "[14]: Station latitude (degrees). A positive value indicates North " 96 | "latitude." 97 | msgstr "[14]: 台站纬度。正值代表北纬。" 98 | 99 | #: ../../appendix/channeltable.rst:24 100 | msgid "" 101 | "[15]: Station longitude (degrees). A positive value indicates East " 102 | "longitude." 103 | msgstr "[15]: 台站经度。正值代表东经。" 104 | 105 | #: ../../appendix/channeltable.rst:25 106 | msgid "[16]: Station height (m)" 107 | msgstr "[16]: 台站高程 (m)" 108 | 109 | #: ../../appendix/channeltable.rst:26 110 | msgid "[17]: Station correction for P-wave (s)" 111 | msgstr "[17]: 台站P波校正 (s)" 112 | 113 | #: ../../appendix/channeltable.rst:27 114 | msgid "[18]: Station correction for S-wave (s)" 115 | msgstr "[18]: 台站S波校正 (s)" 116 | 117 | #: ../../appendix/channeltable.rst:28 118 | msgid "[19]: Station name (Optional)" 119 | msgstr "[19]: 台站名 (可选)" 120 | 121 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/appendix/response.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2018-11-21 16:38-0500\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.6.0\n" 18 | 19 | #: ../../appendix/response.rst:2 20 | msgid "Instrumental Response" 21 | msgstr "仪器响应" 22 | 23 | #: ../../appendix/response.rst:5 24 | msgid "Input" 25 | msgstr "输入" 26 | 27 | #: ../../appendix/response.rst:7 28 | msgid "The unit of Hi-net input is determined by column [9], ususally ``m/s``." 29 | msgstr "Hi-net输入的单位由第9列决定,通常单位是 ``m/s`` 。" 30 | 31 | #: ../../appendix/response.rst:10 32 | msgid "Analog Stage" 33 | msgstr "数字阶段" 34 | 35 | #: ../../appendix/response.rst:12 36 | msgid "" 37 | "The moving coil velocity type seismometer is used in Hi-net and its " 38 | "transfer function in the Laplace domain is given as:" 39 | msgstr "Hi-net使用的是Moving coil velocity type地震仪,其transfer function在Laplace域表示为:" 40 | 41 | #: ../../appendix/response.rst:15 42 | msgid "\\frac{Gs^2}{s^2 + 2hws + w^2}" 43 | msgstr "" 44 | 45 | #: ../../appendix/response.rst:19 46 | msgid "where," 47 | msgstr "其中," 48 | 49 | #: ../../appendix/response.rst:21 50 | msgid ":math:`G`: gain factor, given as column [8] in ``V/unit_of_input``" 51 | msgstr ":math:`G`: 增益因子,在第8列给出,单位为 ``V/unit_of_input``" 52 | 53 | #: ../../appendix/response.rst:22 54 | msgid ":math:`h`: damping constant, given as column [11]" 55 | msgstr ":math:`h`: 阻尼常数,在第11列给出" 56 | 57 | #: ../../appendix/response.rst:23 58 | msgid ":math:`w`: natural angular frequency, given as column [10]" 59 | msgstr ":math:`w`: 自然角频率,在第10列给出" 60 | 61 | #: ../../appendix/response.rst:25 62 | msgid "" 63 | "Roots of the numerator and the denominator correspond to the zeros and " 64 | "the poles, respectively, and the A0 normalization factor is the inverse " 65 | "of the absolute value of the above equation except G at the normalization" 66 | " frequency (:math:`f_n`). The normalization frequency of Hi-net " 67 | "seismometer is always 20 Hz." 68 | msgstr "分子和分母的根分别对应于零点和极点。A0归一化因子是上面方程在归一化频率处的绝对值的倒数。Hi-net地震仪的归一化频率总是20 Hz。" 69 | 70 | #: ../../appendix/response.rst:31 71 | msgid "" 72 | "It's easy to know that the instrumental response has two poles and two " 73 | "zeros. It's also easy to calculate A0, with :math:`s=i*2*\\pi*f_n`." 74 | msgstr "易知,仪器响应有两个极点和零点,将 :math:`s=i*2*\\pi*f_n` 带入可算出 A0。" 75 | 76 | #: ../../appendix/response.rst:35 77 | msgid "Preamplification" 78 | msgstr "放大系数" 79 | 80 | #: ../../appendix/response.rst:37 81 | msgid "" 82 | "The sensor ouput is amplified prior to A/D conversion. The amplification " 83 | "factor is determined by column [12] in dB." 84 | msgstr "传感器的输出在A/D转换之前会进一步放大,归一化因子由第12列(单位dB)决定。" 85 | 86 | #: ../../appendix/response.rst:40 87 | msgid "According to the definition of decibel of field quantities:" 88 | msgstr "根据场物理量的分贝的定义:" 89 | 90 | #: ../../appendix/response.rst:42 91 | msgid "L_{F}=20\\log _{10}\\left({\\frac {F}{F_{0}}}\\right)\\!~\\mathrm {dB} ." 92 | msgstr "" 93 | 94 | #: ../../appendix/response.rst:46 95 | msgid "Thus, the \"sensitivity\" in this stage is :math:`10^{\\frac{[12]}{20}}` ." 96 | msgstr "因而,这一阶段的敏感度是 :math:`10^{\\frac{[12]}{20}}` 。" 97 | 98 | #: ../../appendix/response.rst:49 99 | msgid "Analog-Digital Conversion" 100 | msgstr "模拟-数字转换" 101 | 102 | #: ../../appendix/response.rst:51 103 | msgid "" 104 | "The gain in this stage is given by :math:`\\frac{1}{[13]}`, in " 105 | "``counts/V``." 106 | msgstr "这一阶段的增益是 :math:`\\frac{1}{[13]}` ,单位是 ``counts/V`` 。" 107 | 108 | #: ../../appendix/response.rst:54 109 | msgid "Digital Stage" 110 | msgstr "数字阶段" 111 | 112 | #: ../../appendix/response.rst:56 113 | msgid "" 114 | "The gain in this stage is 1.0, according to the three RESP files provided" 115 | " on Hi-net website." 116 | msgstr "根据Hi-net网站提供的RESP文件可知,这一阶段的增益总是1。" 117 | 118 | #: ../../appendix/response.rst:60 119 | msgid "Summary" 120 | msgstr "总结" 121 | 122 | #: ../../appendix/response.rst:62 123 | msgid "The total sensitivity is:" 124 | msgstr "总的敏感度为:" 125 | 126 | #: ../../appendix/response.rst:64 127 | msgid "G = \\frac{[8]*10^{\\frac{[12]}{20}}}{[13]}" 128 | msgstr "" 129 | 130 | #: ../../appendix/response.rst:68 131 | msgid "The ``CONSTANT`` in SAC PZ file should be:" 132 | msgstr "SAC PZ文件中的 ``CONSTANT`` 应该为:" 133 | 134 | #: ../../appendix/response.rst:70 135 | msgid "CONSTANT = A0 * G = A0 * \\frac{[8]*10^{\\frac{[12]}{20}}}{[13]}" 136 | msgstr "" 137 | 138 | #: ../../appendix/response.rst:76 139 | msgid "" 140 | "HinetPy uses win2sac_32 to do the conversion from win32 to SAC format. " 141 | "win2sac_32 always remove total sensitivity (G) from waveform and multiply" 142 | " by 1.0e9 to convert unit from meter to nanometer." 143 | msgstr "" 144 | "HinetPy 使用 win2sac_32 将win32格式转换为SAC格式。win2sac_32 总是从波形中去除灵敏度 " 145 | "(G),并乘以1.0e9将单位从米变成纳米。" 146 | 147 | #: ../../appendix/response.rst:80 148 | msgid "" 149 | "Thus, the extracted SAC files are velocity in nm/s or acceleration in " 150 | "nm/s/s. The total sensivitity G is also omitted when generating PZ files." 151 | msgstr "因而,提取得到的SAC文件时以 nm/s 为单位的速度或以 nm/s/s 为单位的加速度。总灵敏度 G 也在生成PZ文件时被省去。" 152 | 153 | #: ../../appendix/response.rst:84 154 | msgid "Q&A" 155 | msgstr "" 156 | 157 | #: ../../appendix/response.rst:86 158 | msgid "My question:" 159 | msgstr "我的问题" 160 | 161 | #: ../../appendix/response.rst:88 162 | msgid "Hi," 163 | msgstr "" 164 | 165 | #: ../../appendix/response.rst:90 166 | msgid "" 167 | "I am using Hi-net data and am confused with the instrumental response " 168 | "even after I have looked through all pages of Hi-net website." 169 | msgstr "" 170 | 171 | #: ../../appendix/response.rst:93 172 | msgid "" 173 | "In the page of 'For Registered Users' -> 'Response of Observation " 174 | "Equipment', only three RESP files are given. It seems that I have to " 175 | "rewrite a new RESP or SAC_PZ file for each channel." 176 | msgstr "" 177 | 178 | #: ../../appendix/response.rst:97 179 | msgid "" 180 | "So I have to confirm that I understand details of response, which are " 181 | "very important for correct data processing." 182 | msgstr "" 183 | 184 | #: ../../appendix/response.rst:100 185 | msgid "Do all channels have the same zeroes and poles?" 186 | msgstr "" 187 | 188 | #: ../../appendix/response.rst:101 189 | msgid "" 190 | "At line 19, do all channels have the same A0 Normalization factor " 191 | "(0.999953)?" 192 | msgstr "" 193 | 194 | #: ../../appendix/response.rst:102 195 | msgid "" 196 | "In the FAQ Q08, one equation is given to convert the A/D value from an " 197 | "WIN32 file to the corresponding physical quantity. It is" 198 | msgstr "" 199 | 200 | #: ../../appendix/response.rst:105 201 | msgid "v = I * [13] / ([8] * 10 ^ ([12] / 20 ) )" 202 | msgstr "" 203 | 204 | #: ../../appendix/response.rst:107 205 | msgid "If I want to generate a SAC PZ file, the CONSTANT will be" 206 | msgstr "" 207 | 208 | #: ../../appendix/response.rst:109 209 | msgid "CONSTANT = [8]*10^([12]/20) / [13] * A0 ?" 210 | msgstr "" 211 | 212 | #: ../../appendix/response.rst:111 213 | msgid "Answer from Hi-net:" 214 | msgstr "Hi-net的答案:" 215 | 216 | #: ../../appendix/response.rst:113 217 | msgid "" 218 | "In the \"Response of Observation Equipment\" page, sample RESP files are " 219 | "provided and you need to modify them according to your purposes, as you " 220 | "wrote. The explanation in this page assumes that the parameters of the " 221 | "seismometer other than the gain factor do not change. Strictly speaking, " 222 | "the zeros, the poles, and the A0 normalization factor can change " 223 | "depending on the parameters of the seismometer. The moving coil velocity " 224 | "type seismometer is used in Hi-net and its transfer function in the " 225 | "Laplace domain is given as:" 226 | msgstr "" 227 | 228 | #: ../../appendix/response.rst:122 229 | msgid "Gs^2/(s^2 + 2hws + w^2)" 230 | msgstr "" 231 | 232 | #: ../../appendix/response.rst:124 233 | msgid "" 234 | "where G, h and w are the gain factor, the damping constant, and the " 235 | "natural angular frequency, respectively. Roots of the numerator and the " 236 | "denominator correspond to the zeros and the poles, respectively, and the " 237 | "A0 normalization factor is the inverse of the absolute value of the above" 238 | " equation except G at the normalization frequency. Detailed explanation " 239 | "about this type of seismometer is available in many literature, such as," 240 | msgstr "" 241 | 242 | #: ../../appendix/response.rst:132 243 | msgid "" 244 | "Scherbaum, F., Of Poles and Zeros: Fundamentals of Digital Seismology, " 245 | "Kluwer Academic Publishers, 1996. #see chapter 4" 246 | msgstr "" 247 | 248 | #: ../../appendix/response.rst:136 249 | msgid "" 250 | "The gain factor, the damping constant, and the natural period are " 251 | "provided in the channels table file as explained in the Q&A08. Note that " 252 | "the gain factor is measured at its natural frequency. " 253 | "http://www.hinet.bosai.go.jp/faq/?LANG=en#Q08" 254 | msgstr "" 255 | 256 | #: ../../appendix/response.rst:141 257 | msgid "" 258 | "Please read the SEED manual about further details and SAC manual about " 259 | "SAC PZ file." 260 | msgstr "" 261 | 262 | #: ../../appendix/response.rst:144 263 | msgid "SEED: http://www.fdsn.org/publications.htm" 264 | msgstr "" 265 | 266 | #: ../../appendix/response.rst:145 267 | msgid "SAC: http://www.iris.edu/files/sac-manual/" 268 | msgstr "" 269 | 270 | #: ../../appendix/response.rst:147 271 | msgid "Sincerely," 272 | msgstr "" 273 | 274 | #: ../../appendix/response.rst:151 275 | msgid "`Hi-net FAQ 08 `_" 276 | msgstr "" 277 | 278 | #: ../../appendix/response.rst:152 279 | msgid "" 280 | "`Response of Observation Equipment " 281 | "`_" 282 | msgstr "" 283 | 284 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/appendix/win2sac.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2018-11-21 16:01-0500\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.6.0\n" 18 | 19 | #: ../../appendix/win2sac.rst:2 20 | msgid "win2sac" 21 | msgstr "" 22 | 23 | #: ../../appendix/win2sac.rst:4 24 | msgid "" 25 | "Data converter from WIN32 format to SAC format. It also supports " 26 | "BINARY/ASCII outputs." 27 | msgstr "将WIN32格式转换为SAC格式,也支持BINARY/ASCII格式。" 28 | 29 | #: ../../appendix/win2sac.rst:8 30 | msgid "Usage" 31 | msgstr "用法" 32 | 33 | #: ../../appendix/win2sac.rst:15 34 | msgid "winfile:" 35 | msgstr "" 36 | 37 | #: ../../appendix/win2sac.rst:16 38 | msgid "**one** win32 file to be converted." 39 | msgstr "**一个** 要转换的win32文件。" 40 | 41 | #: ../../appendix/win2sac.rst:21 42 | msgid "ch_no:" 43 | msgstr "" 44 | 45 | #: ../../appendix/win2sac.rst:18 46 | msgid "channle numbers to be extracted. It can be:" 47 | msgstr "要提取的通道号。可以是如下形式:" 48 | 49 | #: ../../appendix/win2sac.rst:20 50 | msgid "a channel number (e.g. ``3345``)" 51 | msgstr "一个通道号(如 ``3345`` )" 52 | 53 | #: ../../appendix/win2sac.rst:21 54 | msgid "a list of channel numbers, separated by commas (e.g. ``3345,3f65,4f75``)" 55 | msgstr "多个用逗号分隔的通道号(如 ``3345,3f65,4f75`` )" 56 | 57 | #: ../../appendix/win2sac.rst:22 58 | msgid "a file contains channel numbers, see details below" 59 | msgstr "一个包含通道号的文件,详情见下面的介绍。" 60 | 61 | #: ../../appendix/win2sac.rst:23 62 | msgid "sacfile" 63 | msgstr "" 64 | 65 | #: ../../appendix/win2sac.rst:24 66 | msgid "extension of output SAC files" 67 | msgstr "输出的SAC文件的后缀" 68 | 69 | #: ../../appendix/win2sac.rst:26 70 | msgid "outdir" 71 | msgstr "" 72 | 73 | #: ../../appendix/win2sac.rst:26 74 | msgid "" 75 | "output directory. Default is current directory if not specified or is " 76 | "``-``. The output directory must exist." 77 | msgstr "输出目录名。若未指定或值为 ``-`` 则默认为当前目录。输出目录必须存在。" 78 | 79 | #: ../../appendix/win2sac.rst:28 80 | msgid "``-p(prmfile)``:" 81 | msgstr "" 82 | 83 | #: ../../appendix/win2sac.rst:29 84 | msgid "specify paramerter file. Default name is ``win.prm``. See details below." 85 | msgstr "指定参数文件。默认文件名是 ``win.prm`` 。详情见下面的介绍。" 86 | 87 | #: ../../appendix/win2sac.rst:30 88 | msgid "``-Y``" 89 | msgstr "" 90 | 91 | #: ../../appendix/win2sac.rst:31 92 | msgid "use wild channel code. organization id + network id + channle id." 93 | msgstr "使用宽通道码。组织ID + 台网ID + 通道ID。" 94 | 95 | #: ../../appendix/win2sac.rst:32 96 | msgid "``-e``" 97 | msgstr "" 98 | 99 | #: ../../appendix/win2sac.rst:33 100 | msgid "" 101 | "specify SAC/BIN output to use endian of current machine. Defaults to use " 102 | "big endian." 103 | msgstr "指定SAC/BIN输出时所使用的字节序。默认使用大字节序。" 104 | 105 | #: ../../appendix/win2sac.rst:34 106 | msgid "``-b[BIN]``" 107 | msgstr "" 108 | 109 | #: ../../appendix/win2sac.rst:35 110 | msgid "extension of BIN format. Defaults to ``bin``." 111 | msgstr "BIN格式文件的后缀。默认值为 ``bin`` 。" 112 | 113 | #: ../../appendix/win2sac.rst:36 114 | msgid "``-a[ASC]``" 115 | msgstr "" 116 | 117 | #: ../../appendix/win2sac.rst:37 118 | msgid "extension of ASC format. Defaults to ``asc``." 119 | msgstr "ASC格式文件的后缀。默认值为 ``asc`` 。" 120 | 121 | #: ../../appendix/win2sac.rst:38 122 | msgid "``-r(RATIO)``" 123 | msgstr "" 124 | 125 | #: ../../appendix/win2sac.rst:39 126 | msgid "the ratio to multiply for BIN/ASC format. Defaults to 1.0." 127 | msgstr "以BIN/ASC格式输出时要乘以的比例。默认值为1.0。" 128 | 129 | #: ../../appendix/win2sac.rst:42 130 | msgid "``-m(PMAX)``" 131 | msgstr "" 132 | 133 | #: ../../appendix/win2sac.rst:41 134 | msgid "" 135 | "maximum number of data points. Defaults to ``2000000``. If you data has " 136 | "more data points, you must increase this value." 137 | msgstr "数据点的最大数目。默认值为 ``2000000`` 。如果你的数据有更多的点数,必须增加该值。" 138 | 139 | #: ../../appendix/win2sac.rst:45 140 | msgid "Examples" 141 | msgstr "示例" 142 | 143 | #: ../../appendix/win2sac.rst:52 144 | msgid "Notes" 145 | msgstr "注解" 146 | 147 | #: ../../appendix/win2sac.rst:55 148 | msgid "Output Unit" 149 | msgstr "输出的单位" 150 | 151 | #: ../../appendix/win2sac.rst:59 152 | msgid "" 153 | "The SAC files extracted by ``win2sac_32`` are always in physical quality," 154 | " not in digital counts." 155 | msgstr "``win2sac_32`` 提取的SAC文件总是真实的物理量,而不是digital counts。" 156 | 157 | #: ../../appendix/win2sac.rst:62 158 | msgid "" 159 | "The raw data saved in win32 format is in digital counts. When extracting " 160 | "data from win32 format, ``win2sac_32`` always convert digital counts to " 161 | "the corresponding physical quantity by remove sensitivity from waveform " 162 | "data, and multiply by 1.0e9 to convert unit from meter to nanometer." 163 | msgstr "" 164 | "win32格式中保存的原始数据是digital counts。当从win32格式中提取数据时, ``win2sac_32`` " 165 | "总是从波形中去除灵敏度以将digital counts转换为对应的物理量,并乘以1.0e9将单位从" 166 | "米转换为纳米。" 167 | 168 | #: ../../appendix/win2sac.rst:67 169 | msgid "The output SAC files are in ``nm/s``, ``nm/s/s`` or ``micro radian``." 170 | msgstr "输出的SAC文件的单位是 ``nm/s`` 、 ``nm/s/s`` 或 ``micro radian``" 171 | 172 | #: ../../appendix/win2sac.rst:70 173 | msgid "Filename Format" 174 | msgstr "文件名格式" 175 | 176 | #: ../../appendix/win2sac.rst:72 177 | msgid "" 178 | "The default filename format is ``STATION.COMPONENT.EXTENSION`` (e.g. " 179 | "``N.NABC.U.SAC``). You can only modify the extensions." 180 | msgstr "默认的文件名格式是 ``STATION.COMPONENT.EXTENSION`` (如 ``N.NABC.U.SAC`` )。你可以修改此后缀名。" 181 | 182 | #: ../../appendix/win2sac.rst:76 183 | msgid "Channel number file format" 184 | msgstr "通道号文件格式" 185 | 186 | #: ../../appendix/win2sac.rst:78 187 | msgid "You can save all channel numbers you want to extract into one file." 188 | msgstr "你可以将所有你要提取数据的通道号保存到一个文件中。" 189 | 190 | #: ../../appendix/win2sac.rst:80 191 | msgid "line starts with ``#`` is comment line and skipped" 192 | msgstr "以 ``#`` 开头的行为注释行会被跳过" 193 | 194 | #: ../../appendix/win2sac.rst:81 195 | msgid "blank lines are skipped" 196 | msgstr "空行会被跳过" 197 | 198 | #: ../../appendix/win2sac.rst:82 199 | msgid "channel numbers can be separated by spaces, tabs, or commas" 200 | msgstr "通道号可以用空格、制表符或逗号分隔" 201 | 202 | #: ../../appendix/win2sac.rst:83 203 | msgid "each line can contain no more than 2000 characters" 204 | msgstr "每行最多不超过2000字符" 205 | 206 | #: ../../appendix/win2sac.rst:85 207 | msgid "Below is an example::" 208 | msgstr "下面是一个示例::" 209 | 210 | #: ../../appendix/win2sac.rst:93 211 | msgid "" 212 | "Using this feature may result in data loss, as ``win2sac_32`` will exit " 213 | "if data of any channel doesn't exist in the win32 file." 214 | msgstr "使用这一特性可能会造成数据损失。因为 ``win2sac_32`` 程序在某个通道的数据不存在时会自动退出。" 215 | 216 | #: ../../appendix/win2sac.rst:96 217 | msgid "" 218 | "If you still want to use this fearture, you can modify Line 386 of " 219 | "``s4win2sacm.c`` from::" 220 | msgstr "如果你依然想要使用这一特性,你需要将 ``s4win2sacm.c`` 的386行从::" 221 | 222 | #: ../../appendix/win2sac.rst:102 223 | msgid "to::" 224 | msgstr "修改为::" 225 | 226 | #: ../../appendix/win2sac.rst:107 227 | msgid "Paramerter file" 228 | msgstr "参数文件" 229 | 230 | #: ../../appendix/win2sac.rst:109 231 | msgid "" 232 | "win32 system need a parameter file to run. This parameter file has many " 233 | "lines. However, ``win2sac_32`` only uses the 2nd and 4th lines, and " 234 | "ignores all other lines." 235 | msgstr "win32系统需要一个参数文件才能执行。这个参数文件有很多行。然而, ``win2sac_32`` 只使用了第2和第4行并忽略其它行。" 236 | 237 | #: ../../appendix/win2sac.rst:112 238 | msgid "An example of a four line parameter file::" 239 | msgstr "四行的参数文件的示例::" 240 | 241 | #: ../../appendix/win2sac.rst:119 242 | msgid "" 243 | "The 2nd line is the name of channle table file. ``win2sac_32`` need to " 244 | "read this file to extract waveform of specified channels." 245 | msgstr "第二行是通道表文件名。 ``win2sac_32`` 需要读取该文件以提取指定通道的波形。" 246 | 247 | #: ../../appendix/win2sac.rst:122 248 | msgid "The 4th line is the path of pick files. It's useless for most cases." 249 | msgstr "第四行是震相拾取文件的路径。大多数情况下都没有用。" 250 | 251 | #: ../../appendix/win2sac.rst:125 252 | msgid "Component" 253 | msgstr "分量" 254 | 255 | #: ../../appendix/win2sac.rst:127 256 | msgid "" 257 | "The component information is written to SAC header variables ``CPMAZ`` " 258 | "and ``CMPINC``." 259 | msgstr "分量信息会被写到SAC头段变量 ``CMPAZ`` 和 ``CMPINC`` 中。" 260 | 261 | #: ../../appendix/win2sac.rst:130 262 | msgid "U/Z: CMPAZ = 0.0, CMPINC = 0.0" 263 | msgstr "" 264 | 265 | #: ../../appendix/win2sac.rst:131 266 | msgid "N/X: CMPAZ = 0.0, CMPINC = 90.0" 267 | msgstr "" 268 | 269 | #: ../../appendix/win2sac.rst:132 270 | msgid "E/Y: CMPAZ = 90.0, CMPINC = 90.0" 271 | msgstr "" 272 | 273 | #: ../../appendix/win2sac.rst:133 274 | msgid "Other: CMPAZ = 0.0, CMPINC = 0.0" 275 | msgstr "" 276 | 277 | #: ../../appendix/win2sac.rst:137 278 | msgid "Azimuths of sensors are **NOT** accurate." 279 | msgstr "传感器的方位角是 **不** 精确的。" 280 | 281 | #: ../../appendix/win2sac.rst:139 282 | msgid "See https://hinetwww11.bosai.go.jp/auth/direc/?LANG=en for details." 283 | msgstr "详情参考 https://hinetwww11.bosai.go.jp/auth/direc/?LANG 。" 284 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/changelog.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2014-2020, Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2020. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.6\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-07-07 23:56+0800\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.13.1\n" 19 | 20 | #: ../../changelog.rst:2 21 | msgid "Changelog" 22 | msgstr "" 23 | 24 | #: ../../changelog.rst:5 25 | msgid "0.9.0 (2024-06-25)" 26 | msgstr "" 27 | 28 | #: ../../changelog.rst:7 29 | msgid "" 30 | "The HinetPy paper is published on JOSS. Check it at " 31 | "https://doi.org/10.21105/joss.06840." 32 | msgstr "" 33 | 34 | #: ../../changelog.rst:10 35 | msgid "0.8.3 (2024-06-05)" 36 | msgstr "" 37 | 38 | #: ../../changelog.rst:12 39 | msgid "" 40 | "Fix the \"OSError: [Errno 18] Invalid cross-device link.\" for cross-" 41 | "system operations." 42 | msgstr "" 43 | 44 | #: ../../changelog.rst:15 45 | msgid "0.8.2 (2024-04-05)" 46 | msgstr "" 47 | 48 | #: ../../changelog.rst:17 49 | msgid "" 50 | "Add the updated solution for the \"ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] " 51 | "dh key too small\" error" 52 | msgstr "" 53 | 54 | #: ../../changelog.rst:20 55 | msgid "0.8.1 (2024-03-31)" 56 | msgstr "" 57 | 58 | #: ../../changelog.rst:22 59 | msgid "Minor changes to simplify some internal functions." 60 | msgstr "" 61 | 62 | #: ../../changelog.rst:25 63 | msgid "0.8.0 (2024-03-28)" 64 | msgstr "" 65 | 66 | #: ../../changelog.rst:27 67 | msgid "Support more newly added networks" 68 | msgstr "" 69 | 70 | #: ../../changelog.rst:28 71 | msgid "" 72 | "Remove the hacking solution for SSL connection issue so it works well " 73 | "with urllib3 v2.x" 74 | msgstr "" 75 | 76 | #: ../../changelog.rst:29 77 | msgid "Drop support for Python 3.7." 78 | msgstr "" 79 | 80 | #: ../../changelog.rst:32 81 | msgid "0.7.1 (2022-07-08)" 82 | msgstr "" 83 | 84 | #: ../../changelog.rst:34 85 | msgid "Fix bugs in ``get_event_waveform``" 86 | msgstr "" 87 | 88 | #: ../../changelog.rst:37 89 | msgid "0.7.0 (2022-07-01)" 90 | msgstr "" 91 | 92 | #: ../../changelog.rst:39 93 | msgid "Fix the incorrect maximum allowed time span for F-net (#65)" 94 | msgstr "" 95 | 96 | #: ../../changelog.rst:40 97 | msgid "" 98 | "``get_selected_stations`` now returns a list of stations with station " 99 | "metadata information (#36)" 100 | msgstr "" 101 | 102 | #: ../../changelog.rst:41 103 | msgid "" 104 | "Refactor the ``_channel2pz()`` and ``_write_pz()`` functions to " 105 | "``Channel.write_sacpz()``" 106 | msgstr "" 107 | 108 | #: ../../changelog.rst:42 109 | msgid "Refactor the ``_get_channels`` function to ``win32.read_ctable()``" 110 | msgstr "" 111 | 112 | #: ../../changelog.rst:43 113 | msgid "The ``win32.extrac_sacpz`` function now supports parallel data processing" 114 | msgstr "" 115 | 116 | #: ../../changelog.rst:44 117 | msgid "" 118 | "The ``with_pz`` parameter in ``win32.extract_sac()`` is renamed to " 119 | "``with_sacpz``" 120 | msgstr "" 121 | 122 | #: ../../changelog.rst:45 123 | msgid "The ``win32.extrac_pz()`` function is renamed to ``win32.extract_sacpz()``" 124 | msgstr "" 125 | 126 | #: ../../changelog.rst:46 127 | msgid "" 128 | "Move the function ``Client.check_cmd_exists()`` to " 129 | "``utils.check_cmd_exists()``" 130 | msgstr "" 131 | 132 | #: ../../changelog.rst:47 133 | msgid "" 134 | "Move the function ``Client.check_package_release()`` to " 135 | "``utils.check_package_release()``" 136 | msgstr "" 137 | 138 | #: ../../changelog.rst:48 139 | msgid "Fix the \"ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small\" error" 140 | msgstr "" 141 | 142 | #: ../../changelog.rst:51 143 | msgid "0.6.9 (2021-05-20)" 144 | msgstr "" 145 | 146 | #: ../../changelog.rst:53 147 | msgid "Check invalid ``stations`` parameter type for ``Client.select_stations()``" 148 | msgstr "" 149 | 150 | #: ../../changelog.rst:56 151 | msgid "0.6.8 (2021-03-11)" 152 | msgstr "" 153 | 154 | #: ../../changelog.rst:58 155 | msgid "include_unknown_mag does not work in get_event_waveform()" 156 | msgstr "" 157 | 158 | #: ../../changelog.rst:59 159 | msgid "Fail to download S-net data." 160 | msgstr "" 161 | 162 | #: ../../changelog.rst:62 163 | msgid "0.6.7 (2020-06-08)" 164 | msgstr "" 165 | 166 | #: ../../changelog.rst:64 167 | msgid "Improve code styles, tests and CI." 168 | msgstr "" 169 | 170 | #: ../../changelog.rst:67 171 | msgid "0.6.6 (2020-03-02)" 172 | msgstr "" 173 | 174 | #: ../../changelog.rst:69 175 | msgid "win32.extract_pz cannot filter channels by ID and name (#27)" 176 | msgstr "" 177 | 178 | #: ../../changelog.rst:72 179 | msgid "0.6.5 (2019-12-06)" 180 | msgstr "" 181 | 182 | #: ../../changelog.rst:74 183 | msgid "Fix PZ files if damping constant is zero (#24)" 184 | msgstr "" 185 | 186 | #: ../../changelog.rst:77 187 | msgid "0.6.4 (2019-08-23)" 188 | msgstr "" 189 | 190 | #: ../../changelog.rst:79 191 | msgid "Capture exception caused by incorrect channel information (#22)" 192 | msgstr "" 193 | 194 | #: ../../changelog.rst:82 195 | msgid "0.6.3 (2019-06-13)" 196 | msgstr "" 197 | 198 | #: ../../changelog.rst:84 199 | msgid "Fix ``select_stations()`` (#19)" 200 | msgstr "" 201 | 202 | #: ../../changelog.rst:85 203 | msgid "Rename ``string2datetime()`` to ``to_datetime()``" 204 | msgstr "" 205 | 206 | #: ../../changelog.rst:88 207 | msgid "0.6.2 (2019-05-06)" 208 | msgstr "" 209 | 210 | #: ../../changelog.rst:90 211 | msgid "Fix download focal mechanism catalog issue (#18)." 212 | msgstr "" 213 | 214 | #: ../../changelog.rst:93 215 | msgid "0.6.1 (2019-02-20)" 216 | msgstr "" 217 | 218 | #: ../../changelog.rst:95 219 | msgid "Fix selecting events in a rectangular region." 220 | msgstr "" 221 | 222 | #: ../../changelog.rst:98 223 | msgid "0.6.0 (2019-02-19)" 224 | msgstr "" 225 | 226 | #: ../../changelog.rst:100 227 | msgid "Support request event waveform data (#16)." 228 | msgstr "" 229 | 230 | #: ../../changelog.rst:101 231 | msgid "``get_waveform()`` is renamed to ``get_continuous_waveform()``." 232 | msgstr "" 233 | 234 | #: ../../changelog.rst:104 235 | msgid "0.5.2 (2019-02-19)" 236 | msgstr "" 237 | 238 | #: ../../changelog.rst:106 239 | msgid "Fix selecting stations in a rectangular region (#17)." 240 | msgstr "" 241 | 242 | #: ../../changelog.rst:109 243 | msgid "0.5.1 (2018-12-08)" 244 | msgstr "" 245 | 246 | #: ../../changelog.rst:111 247 | msgid "Fix typo from longtitude to longitude." 248 | msgstr "" 249 | 250 | #: ../../changelog.rst:114 251 | msgid "0.5.0 (2018-11-21)" 252 | msgstr "" 253 | 254 | #: ../../changelog.rst:116 255 | msgid "Fix issues of wrong CONSTANT in SAC polezero file (#8)." 256 | msgstr "" 257 | 258 | #: ../../changelog.rst:117 259 | msgid "Fix login failure issue with password longer than 12 characters (#13)." 260 | msgstr "" 261 | 262 | #: ../../changelog.rst:120 263 | msgid "0.4.8 (2018-10-04)" 264 | msgstr "" 265 | 266 | #: ../../changelog.rst:122 267 | msgid "" 268 | "``get_station_list()``: must specify a network code; support S-net and " 269 | "MeSO-net." 270 | msgstr "" 271 | 272 | #: ../../changelog.rst:123 273 | msgid "``select_stations()``: support S-net and MeSO-net" 274 | msgstr "" 275 | 276 | #: ../../changelog.rst:126 277 | msgid "0.4.7 (2018-10-04)" 278 | msgstr "" 279 | 280 | #: ../../changelog.rst:128 281 | msgid "Support S-net and MeSO-net (#9 and #10)" 282 | msgstr "" 283 | 284 | #: ../../changelog.rst:129 285 | msgid "Fix an issue when channel table contains blank lines" 286 | msgstr "" 287 | 288 | #: ../../changelog.rst:132 289 | msgid "0.4.6 (2018-03-20)" 290 | msgstr "" 291 | 292 | #: ../../changelog.rst:134 293 | msgid "Fix ``Too many open files`` (#6)" 294 | msgstr "" 295 | 296 | #: ../../changelog.rst:137 297 | msgid "0.4.5 (2018-03-07)" 298 | msgstr "" 299 | 300 | #: ../../changelog.rst:139 301 | msgid "``get_station_list()``: return a list of stations" 302 | msgstr "" 303 | 304 | #: ../../changelog.rst:140 305 | msgid "" 306 | "``select_stations()``: support selecting stations in a box or circular " 307 | "region" 308 | msgstr "" 309 | 310 | #: ../../changelog.rst:143 311 | msgid "0.4.4 (2017-11-30)" 312 | msgstr "" 313 | 314 | #: ../../changelog.rst:145 315 | msgid "Fix a technical issue related to packaging" 316 | msgstr "" 317 | 318 | #: ../../changelog.rst:148 319 | msgid "0.4.3 (2017-11-30)" 320 | msgstr "" 321 | 322 | #: ../../changelog.rst:150 323 | msgid "Add Chinese documentation" 324 | msgstr "" 325 | 326 | #: ../../changelog.rst:153 327 | msgid "0.4.2 (2017-06-18)" 328 | msgstr "" 329 | 330 | #: ../../changelog.rst:155 331 | msgid "Fix a bug with requests>=2.17" 332 | msgstr "" 333 | 334 | #: ../../changelog.rst:158 335 | msgid "0.4.1 (2017-06-18)" 336 | msgstr "" 337 | 338 | #: ../../changelog.rst:160 339 | msgid "remove tempfile after downloading." 340 | msgstr "" 341 | 342 | #: ../../changelog.rst:163 343 | msgid "0.4.0 (2017-04-01)" 344 | msgstr "" 345 | 346 | #: ../../changelog.rst:165 347 | msgid "``win32.extract_sac()``: skip if data not exists" 348 | msgstr "" 349 | 350 | #: ../../changelog.rst:166 351 | msgid "" 352 | "``win32.extract_sac()``: support multiple processes to speedup, and no " 353 | "longer return values" 354 | msgstr "" 355 | 356 | #: ../../changelog.rst:167 357 | msgid "``Client.get_waveform()``: support multi-threads to speedup" 358 | msgstr "" 359 | 360 | #: ../../changelog.rst:168 361 | msgid "Change ``Client.help()`` to ``Client.info()``" 362 | msgstr "" 363 | 364 | #: ../../changelog.rst:169 365 | msgid "``Client.get_waveform()`` now can automatically set ``max_span``" 366 | msgstr "" 367 | 368 | #: ../../changelog.rst:170 369 | msgid "``Client.get_*()`` now support startime in different string formats" 370 | msgstr "" 371 | 372 | #: ../../changelog.rst:173 373 | msgid "0.3.3 (2017-03-17)" 374 | msgstr "" 375 | 376 | #: ../../changelog.rst:175 377 | msgid "Change ``network`` to ``NETWORK`` in ``header.py``" 378 | msgstr "" 379 | 380 | #: ../../changelog.rst:176 381 | msgid "Add wildcard support to ``win32.merge()``" 382 | msgstr "" 383 | 384 | #: ../../changelog.rst:177 385 | msgid "" 386 | "Change ``Client.check_module_release()`` to " 387 | "``Client.check_package_release()``" 388 | msgstr "" 389 | 390 | #: ../../changelog.rst:178 391 | msgid "Support output filename with deep directory" 392 | msgstr "" 393 | 394 | #: ../../changelog.rst:179 395 | msgid "Always sort cnt files to avoid merge error" 396 | msgstr "" 397 | 398 | #: ../../changelog.rst:180 399 | msgid "Set ``pmax`` to 8640000 by default" 400 | msgstr "" 401 | 402 | #: ../../changelog.rst:181 403 | msgid "Fix typos" 404 | msgstr "" 405 | 406 | #: ../../changelog.rst:184 407 | msgid "0.3.2 (2017-03-12)" 408 | msgstr "" 409 | 410 | #: ../../changelog.rst:186 411 | msgid "Fix another technical issue related to pypi" 412 | msgstr "" 413 | 414 | #: ../../changelog.rst:189 415 | msgid "0.3.1 (2017-03-12)" 416 | msgstr "" 417 | 418 | #: ../../changelog.rst:191 419 | msgid "Fix a technical issue related to pypi" 420 | msgstr "" 421 | 422 | #: ../../changelog.rst:194 423 | msgid "0.3.0 (2017-03-12)" 424 | msgstr "" 425 | 426 | #: ../../changelog.rst:196 427 | msgid "Rewritten as a Python package" 428 | msgstr "" 429 | 430 | #: ../../changelog.rst:199 431 | msgid "0.2.0 (2016-08-24)" 432 | msgstr "" 433 | 434 | #: ../../changelog.rst:201 435 | msgid "Some small fixes and improvements" 436 | msgstr "" 437 | 438 | #: ../../changelog.rst:204 439 | msgid "0.1.0 (2016-08-04)" 440 | msgstr "" 441 | 442 | #: ../../changelog.rst:206 443 | msgid "First public release" 444 | msgstr "" 445 | 446 | #: ../../changelog.rst:207 447 | msgid "``HinetDoctor.py``: check dependencies" 448 | msgstr "" 449 | 450 | #: ../../changelog.rst:208 451 | msgid "``HinetContRequest.py``: request continuous data from Hi-net" 452 | msgstr "" 453 | 454 | #: ../../changelog.rst:209 455 | msgid "" 456 | "``StationSelector.py``: select Hi-net/F-net stations before requesting " 457 | "data" 458 | msgstr "" 459 | 460 | #: ../../changelog.rst:210 461 | msgid "``HinetJMARequest.py``: request JMA catalogs from Hi-net website" 462 | msgstr "" 463 | 464 | #: ../../changelog.rst:211 465 | msgid "``rdhinet.py``: convert WIN32 format to SAC format" 466 | msgstr "" 467 | 468 | #: ../../changelog.rst:212 469 | msgid "``ch2pz.py``: extract SAC PZ files from Hi-net channel table files" 470 | msgstr "" 471 | 472 | #~ msgid "0.6.6 (2020-03-02):" 473 | #~ msgstr "" 474 | 475 | #~ msgid "0.6.5 (2019-12-06):" 476 | #~ msgstr "" 477 | 478 | #~ msgid "Fix PZ files if dampling constant is zero (#24)" 479 | #~ msgstr "" 480 | 481 | #~ msgid "0.6.4 (2019-08-23):" 482 | #~ msgstr "" 483 | 484 | #~ msgid "0.6.3 (2019-06-13):" 485 | #~ msgstr "" 486 | 487 | #~ msgid "0.6.2 (2019-05-06):" 488 | #~ msgstr "" 489 | 490 | #~ msgid "0.6.1 (2019-02-20):" 491 | #~ msgstr "" 492 | 493 | #~ msgid "0.6.0 (2019-02-19):" 494 | #~ msgstr "" 495 | 496 | #~ msgid "0.5.2 (2019-02-19):" 497 | #~ msgstr "" 498 | 499 | #~ msgid "0.5.1 (2018-12-08):" 500 | #~ msgstr "" 501 | 502 | #~ msgid "0.5.0 (2018-11-21):" 503 | #~ msgstr "" 504 | 505 | #~ msgid "0.4.8 (2018-10-04):" 506 | #~ msgstr "" 507 | 508 | #~ msgid "0.4.7 (2018-10-04):" 509 | #~ msgstr "" 510 | 511 | #~ msgid "0.4.6 (2018-03-20):" 512 | #~ msgstr "" 513 | 514 | #~ msgid "0.4.5 (2018-03-07):" 515 | #~ msgstr "" 516 | 517 | #~ msgid "0.4.4 (2017-11-30):" 518 | #~ msgstr "" 519 | 520 | #~ msgid "0.4.3 (2017-11-30):" 521 | #~ msgstr "" 522 | 523 | #~ msgid "0.4.2 (2017-06-18):" 524 | #~ msgstr "" 525 | 526 | #~ msgid "0.4.1 (2017-06-18):" 527 | #~ msgstr "" 528 | 529 | #~ msgid "0.4.0 (2017-04-01):" 530 | #~ msgstr "" 531 | 532 | #~ msgid "0.3.3 (2017-03-17):" 533 | #~ msgstr "" 534 | 535 | #~ msgid "0.3.2 (2017-03-12):" 536 | #~ msgstr "" 537 | 538 | #~ msgid "0.3.1 (2017-03-12):" 539 | #~ msgstr "" 540 | 541 | #~ msgid "0.3.0 (2017-03-12):" 542 | #~ msgstr "" 543 | 544 | #~ msgid "0.2.0 (2016-08-24):" 545 | #~ msgstr "" 546 | 547 | #~ msgid "0.1.0 (2016-08-04):" 548 | #~ msgstr "" 549 | 550 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/examples.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.4.0\n" 19 | 20 | #: ../../examples.rst:2 21 | msgid "Examples" 22 | msgstr "示例" 23 | 24 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/examples/example1.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2019-02-19 17:30-0500\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.6.0\n" 18 | 19 | #: ../../examples/example1.rst:2 20 | msgid "Request continuous waveform data from CSV catalog" 21 | msgstr "根据CSV地震目录申请连续波形数据" 22 | 23 | #: ../../examples/example1.rst:4 24 | msgid "" 25 | "This example shows how to request waveform data based on a catalog in CSV" 26 | " format." 27 | msgstr "这个例子展示了如何根据CSV格式的地震目录申请波形数据。" 28 | 29 | #: ../../examples/example1.rst:6 30 | msgid "" 31 | "Below is an example catalog file in CSV format. The catalog is obtained " 32 | "from `IRIS web service `_." 33 | msgstr "" 34 | "下面的CSV格式的示例地震目录来自于 `IRIS web service " 35 | "`_ 。" 36 | 37 | #: ../../examples/example1.rst:12 38 | msgid "Python script:" 39 | msgstr "Python脚本" 40 | 41 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/examples/example2.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2019-02-19 17:30-0500\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.6.0\n" 19 | 20 | #: ../../examples/example2.rst:2 21 | msgid "Request continous waveform data from obspy Catalog" 22 | msgstr "根据obspy Catalog申请连续波形数据" 23 | 24 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/index.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-07-07 23:56+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.13.1\n" 18 | 19 | #: ../../index.rst:2 20 | msgid "HinetPy" 21 | msgstr "" 22 | 23 | #: ../../../README.rst:3 24 | msgid "" 25 | "`HinetPy `_ is a Python package for " 26 | "accessing and processing seismic data from `NIED Hi-net " 27 | "`__." 28 | msgstr "" 29 | "`HinetPy `_ 是一个可用于申请和处理 `NIED Hi-net " 30 | "`__ 地震数据的 Python 包。" 31 | 32 | #: ../../../README.rst:7 33 | msgid "Key Features" 34 | msgstr "主要功能" 35 | 36 | #: ../../../README.rst:9 37 | msgid "" 38 | "Facilitates easy access to NIED Hi-net seismic data, including " 39 | "continuous/event waveform data and event catalogs." 40 | msgstr "方便访问 NIED Hi-net 地震数据,包括连续/事件波形数据和事件目录。" 41 | 42 | #: ../../../README.rst:11 43 | msgid "" 44 | "Supports multiple seismic networks (e.g., F-net, S-net, MeSO-net and more" 45 | " in addition to Hi-net) in Japan." 46 | msgstr "支持日本多个地震台网(如 Hi-net、F-net、S-net、MeSO-net 等)。" 47 | 48 | #: ../../../README.rst:13 49 | msgid "" 50 | "Selects a subset of stations based on geographical location or station " 51 | "name (Supports Hi-net, F-net, S-net and MeSO-net only)." 52 | msgstr "根据地理位置或台站名称选择台站子集(仅支持 Hi-net、F-net、S-net 和 MeSO-net)。" 53 | 54 | #: ../../../README.rst:15 55 | msgid "" 56 | "Converts waveform data to SAC format and instrumental responses to SAC " 57 | "polezero files." 58 | msgstr "将波形数据转换为 SAC 格式,将仪器响应转换为 SAC 极零文件。" 59 | 60 | #: ../../../README.rst:16 61 | msgid "" 62 | "Speeds up the downloading and processing workflow via the use of " 63 | "multithreading." 64 | msgstr "通过使用多线程,加快下载和处理工作流程。" 65 | 66 | #: ../../../README.rst:19 67 | msgid "A simple example" 68 | msgstr "一个简单的示例" 69 | 70 | #: ../../../README.rst:21 71 | msgid "" 72 | "Here is an example showing how to use HinetPy to request continuous " 73 | "waveform data from Hi-net, convert the data into SAC format, and extract " 74 | "instrumental responses as SAC polezero files." 75 | msgstr "下面的示例展示了如何使用 HinetPy 从 Hi-net 申请连续波形数据,将数据转换为 SAC 格式,并提取 SAC 零极点格式的仪器响应文件。" 76 | 77 | #: ../../../README.rst:60 78 | msgid "Citation" 79 | msgstr "引用" 80 | 81 | #: ../../../README.rst:62 82 | msgid "" 83 | "If you find this package useful, please consider cite the package in " 84 | "either of the following ways:" 85 | msgstr "如果你觉得这个软件包很有用,请考虑通过如下方式中的任一种引用该软件:" 86 | 87 | #: ../../../README.rst:65 88 | msgid "**Cite the HinetPy paper (preferred)**" 89 | msgstr "**引用 HinetPy 的文章(推荐)**" 90 | 91 | #: ../../../README.rst:67 92 | msgid "" 93 | "A formal paper is published on `The Journal of Open Source Software " 94 | "`__ since HinetPy v0.9.0. This is the " 95 | "**preferred** way for citation." 96 | msgstr "自 HinetPy v0.9.0 起,HinetPy 的介绍文章发表在 `The Journal of Open Source Software " 97 | "`__ 上。这是首选的引用方式。" 98 | 99 | #: ../../../README.rst:70 100 | msgid "" 101 | "Tian, D. (2024). HinetPy: A Python package for accessing and processing " 102 | "NIED Hi-net seismic data. Journal of Open Source Software, 9(98), 6840. " 103 | "https://doi.org/10.21105/joss.06840" 104 | msgstr "" 105 | 106 | #: ../../../README.rst:73 107 | msgid "**Cite a specific HinetPy version**" 108 | msgstr "**引用特定的 HinetPy 版本**" 109 | 110 | #: ../../../README.rst:75 111 | msgid "" 112 | "If you'd like to cite a specific HinetPy version, you can visit `Zenodo " 113 | "`__, choose the version you want to " 114 | "cite, and cite like this:" 115 | msgstr "如果想引用特定的 HinetPy 版本,可以访问 `Zenodo `__," 116 | "选择要引用的版本,然后像这样引用:" 117 | 118 | #: ../../../README.rst:79 119 | msgid "" 120 | "Tian, D. (20XX). HinetPy: A Python package for accessing and processing " 121 | "NIED Hi-net seismic data (X.X.X). Zenodo. " 122 | "https://doi.org/10.5281/zenodo.xxxxxxxx" 123 | msgstr "" 124 | 125 | #: ../../../README.rst:83 126 | msgid "Contributing" 127 | msgstr "贡献指南" 128 | 129 | #: ../../../README.rst:85 130 | msgid "" 131 | "Feedback and contributions are welcome! Please feel free to open an issue" 132 | " or pull request if you have any suggestions or would like to contribute " 133 | "a feature. For additional information or specific questions, please open " 134 | "an issue directly." 135 | msgstr "欢迎反馈和贡献!如果您有任何建议或想贡献一项功能,请新建一个 issue 或 pull request。" 136 | "如需其他信息或具体问题,请直接提交 issue。" 137 | 138 | #: ../../../README.rst:90 139 | msgid "License" 140 | msgstr "许可协议" 141 | 142 | #: ../../../README.rst:92 143 | msgid "This project is licensed under the terms of the MIT license." 144 | msgstr "本项目使用 MIT 许可协议。" 145 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/installation.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2022-02-17 21:21+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.9.1\n" 18 | 19 | #: ../../installation.rst:2 20 | msgid "Installation" 21 | msgstr "安装" 22 | 23 | #: ../../installation.rst:5 24 | msgid "Prerequisites" 25 | msgstr "准备工作" 26 | 27 | #: ../../installation.rst:7 28 | msgid "To use HinetPy, you need:" 29 | msgstr "为了使用 HinetPy,你需要:" 30 | 31 | #: ../../installation.rst:9 32 | msgid "Python >= 3.8" 33 | msgstr "" 34 | 35 | #: ../../installation.rst:10 36 | msgid "win32tools provided by NIED Hi-net (see below for install instructions)" 37 | msgstr "NIED Hi-net 提供的 win32tools (安装指南见下面)" 38 | 39 | #: ../../installation.rst:11 40 | msgid "" 41 | "a Hi-net account (register on Hi-net website to get your user name and " 42 | "password)" 43 | msgstr "Hi-net 账户(需要在 Hi-net 网站注册获取账号密码)" 44 | 45 | #: ../../installation.rst:14 46 | msgid "Install HinetPy" 47 | msgstr "安装 HinetPy" 48 | 49 | #: ../../installation.rst:16 50 | msgid "To install the latest **release/stable** version::" 51 | msgstr "安装最新的\\ **发布版/稳定版**::" 52 | 53 | #: ../../installation.rst:20 54 | msgid "Or install the **developing/unstable** version::" 55 | msgstr "安装最新的\\ **开发版/不稳定版**::" 56 | 57 | #: ../../installation.rst:26 58 | msgid "If you want to uninstall HinetPy, just run::" 59 | msgstr "如果想要卸载 HinetPy,直接执行::" 60 | 61 | #: ../../installation.rst:31 62 | msgid "Build win32tools" 63 | msgstr "编译 win32tools" 64 | 65 | #: ../../installation.rst:33 66 | msgid "" 67 | "`win32tools`_ is a collection of tools provided by `NIED Hi-net`_ to " 68 | "process win32 format data. HinetPy needs the ``catwin32`` and " 69 | "``win2sac_32`` commands to process the win32 data." 70 | msgstr "" 71 | "`win32tools`_ 是 `NIED Hi-net`_ 提供的用于处理win32格式数据的一系列工具。HinetPy 需要其中的 " 72 | "``catwin32`` 和 ``win2sac_32``\\ 。" 73 | 74 | #: ../../installation.rst:37 75 | msgid "Run the following commands to build win32tools::" 76 | msgstr "执行如下命令以编译 win32tools::" 77 | 78 | #: ../../installation.rst:43 79 | msgid "" 80 | "For macOS users, the above command may fail with an fatal error like " 81 | "this::" 82 | msgstr "对于 macOS 用户,执行上面的命令可能会产生如下错误::" 83 | 84 | #: ../../installation.rst:51 85 | msgid "" 86 | "In this case, you should change ``#include `` to ``#include " 87 | "`` at line 3 of ``win2sac.src/s4read_data.c``." 88 | msgstr "" 89 | "遇到这种情况,你需要将 ``win2sac.src/s4read_data.c`` 第三行的 ``#include " 90 | "\"\"`` 修改为 ``#include ``\\ 。" 91 | 92 | #: ../../installation.rst:54 93 | msgid "" 94 | "After successfully building win32tools, you need to make sure that " 95 | "``catwin32`` and ``win2sac_32`` are in your PATH. You can simply run the " 96 | "following command to copy the two commands into your HOME's bin " 97 | "directory::" 98 | msgstr "" 99 | "成果编译 win32tools 后,你还需要确保 ``catwin32`` 和 ``win2sac_32`` 位于你的 PATH " 100 | "路径中。你可以直接执行如下命令将这两个可执行文件复制到你的 HOME 的 bin 目录下::" 101 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/license.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | "Project-Id-Version: HinetPy 0.6.1\n" 7 | "Report-Msgid-Bugs-To: \n" 8 | "POT-Creation-Date: 2017-07-22 12:08+0800\n" 9 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 10 | "Last-Translator: FULL NAME \n" 11 | "Language-Team: LANGUAGE \n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=utf-8\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | "Generated-By: Babel 2.4.0\n" 16 | 17 | #: ../../license.rst:2 18 | msgid "License" 19 | msgstr "许可协议" 20 | 21 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.4.0\n" 18 | 19 | #: ../../tutorial.rst:2 20 | msgid "Tutorial" 21 | msgstr "教程" 22 | 23 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial/conversion.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-07-07 23:56+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.13.1\n" 18 | 19 | #: ../../tutorial/conversion.rst:2 20 | msgid "Data conversion" 21 | msgstr "数据转换" 22 | 23 | #: ../../tutorial/conversion.rst:4 24 | msgid "" 25 | "Hi-net provide waveform data in win32 format and instrument responses in " 26 | "a channel table. :mod:`~HinetPy.win32` can convert them into SAC and SAC " 27 | "polezero formats." 28 | msgstr "" 29 | "Hi-net提供了win32格式的波形数据和通道表形式的仪器响应。 :mod:`~HinetPy.win32` " 30 | "可以将其转换为SAC和SAC零极点格式。" 31 | 32 | #: ../../tutorial/conversion.rst:12 33 | msgid "Extract Waveform Data" 34 | msgstr "提取波形数据" 35 | 36 | #: ../../tutorial/conversion.rst:14 37 | msgid "Extract waveform data of all channels as SAC format." 38 | msgstr "提取所有通道的数据数据并保存为SAC格式。" 39 | 40 | #: ../../tutorial/conversion.rst:20 41 | msgid "The SAC files converted from win32 format are **NOT** in digital counts!!!" 42 | msgstr "从win32格式转换得到的SAC文件的单位不是digital counts!!!" 43 | 44 | #: ../../tutorial/conversion.rst:22 45 | msgid "" 46 | "``win2sac_32`` automatically removes sensitivity from waveforms and " 47 | "multipy by 1.0e9. Thus, the SAC files are velocity in nm/s or " 48 | "accelaration in nm/s/s." 49 | msgstr "" 50 | "``win2sac_32`` 会自动从波形中去除灵敏度,并乘以1.0e9。因而,SAC文件是以 nm/s 为单位的速度或以 nm/s/s " 51 | "为单位的加速度。" 52 | 53 | #: ../../tutorial/conversion.rst:26 54 | msgid "" 55 | "The SAC files have a default filename ``STATION.COMPONENT.SAC`` (e.g. " 56 | "``N.NABC.U.SAC``). You can specify another SAC suffix and a different " 57 | "output directory." 58 | msgstr "" 59 | "SAC文件的默认文件名格式为 ``STATION.COMPONENT.SAC`` (例如 ``N.NABC.U.SAC`` " 60 | ")。你可以指定其他SAC文件后缀和输出目录。" 61 | 62 | #: ../../tutorial/conversion.rst:31 ../../tutorial/conversion.rst:65 63 | msgid "" 64 | "If you want to extract only a small subset of channels, you can use " 65 | "``filter_by_id``, ``filter_by_name`` and/or ``filter_by_component`` to " 66 | "filter the channels. They accept a list of string or a string contains " 67 | "wildcard." 68 | msgstr "" 69 | "如果你只想提取一部分通道的波形数据,你可以使用 ``filter_by_id`` 、 ``filter_by_name`` 和/或 " 70 | "``filter_by_component`` 以筛选需要的通道。这些参数都可以接受字符串列表或者包含通配符的字符串。" 71 | 72 | #: ../../tutorial/conversion.rst:43 73 | msgid "Extract PZ" 74 | msgstr "提取零极点文件" 75 | 76 | #: ../../tutorial/conversion.rst:45 77 | msgid "" 78 | ":meth:`~HinetPy.win32.extract_sacpz` can convert instrumental responses " 79 | "from Hi-net's channel table to SAC PZ format." 80 | msgstr ":meth:`~HinetPy.win32.extract_sacpz` 可以将仪器响应从Hi-net的通道表格式转换为SAC PZ格式。" 81 | 82 | #: ../../tutorial/conversion.rst:50 83 | msgid "This function works for Hi-net network only." 84 | msgstr "此功能仅对Hi-net台网有效。" 85 | 86 | #: ../../tutorial/conversion.rst:52 87 | msgid "" 88 | "F-net data users are highly recommended to use `FnetPy " 89 | "`_ to request waveform data in SEED " 90 | "format and extract instrumental responses in RESP or PZ format from SEED " 91 | "files." 92 | msgstr "" 93 | "强烈建议F-net数据用户使用 `FnetPy `_ " 94 | "从Fnet网站申请SEED格式的数据,并从SEED文件中提取RESP或PZ格式的仪器响应。" 95 | 96 | #: ../../tutorial/conversion.rst:56 97 | msgid "Extract information of all channels as SACPZ file:" 98 | msgstr "提取所有通道的仪器响应并保存为SACPZ文件:" 99 | 100 | #: ../../tutorial/conversion.rst:60 101 | msgid "" 102 | "The SACPZ file has a default name ``STATION.COMPONENT.SAC_PZ`` (e.g. " 103 | "``N.NABC.U.SAC_PZ``). You can specify another SACPZ suffix and a " 104 | "different output directory." 105 | msgstr "" 106 | "SACPZ文件的默认文件名格式为 ``STATION.COMPONENT.SAC_PZ`` (例如 ``N.NABC.U.SAC_PZ`` " 107 | ")。你可以指定其他SACPZ文件后缀和输出目录。" 108 | 109 | #: ../../tutorial/conversion.rst:78 110 | msgid "" 111 | "`Response of Observation Equipment " 112 | "`_" 113 | msgstr "" 114 | 115 | #: ../../tutorial/conversion.rst:79 116 | msgid "`Hi-net FAQ Q08 `_" 117 | msgstr "" 118 | 119 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial/get-catalog.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2017-07-22 12:20+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.4.0\n" 18 | 19 | #: ../../tutorial/get_catalog.rst:2 20 | msgid "Get Catalog" 21 | msgstr "获取目录" 22 | 23 | #: ../../tutorial/get_catalog.rst:5 24 | msgid "Get arrival time catalog" 25 | msgstr "获取走时目录" 26 | 27 | #: ../../tutorial/get_catalog.rst:7 28 | msgid "Hi-net provide JMA arrivaltime data for downloading." 29 | msgstr "Hi-net提供了JMA走时数据供下载。" 30 | 31 | #: ../../tutorial/get_catalog.rst:17 32 | msgid "Get focal mechanism catalog" 33 | msgstr "获取震源机制解目录" 34 | 35 | #: ../../tutorial/get_catalog.rst:19 36 | msgid "Hi-net provide JMA focal mechanism catalog for downloading." 37 | msgstr "Hi-net提供了JMA震源机制解目录供下载。" 38 | 39 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial/get-continuous-waveform.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2019-02-19 17:35-0500\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.6.0\n" 18 | 19 | #: ../../tutorial/get-continuous-waveform.rst:2 20 | msgid "Get continuous waveform" 21 | msgstr "获取连续波形数据" 22 | 23 | #: ../../tutorial/get-continuous-waveform.rst:4 24 | msgid "" 25 | "This tutorial shows how to use " 26 | ":meth:`~HinetPy.client.Client.get_continuous_waveform` to request continuous " 27 | "waveform data from Hi-net in different ways." 28 | msgstr "本教程将展示如何通过 :meth:`~HinetPy.client.Client.get_continuous_waveform` 用多种方式从Hi-net申请连续波形数据。" 29 | 30 | #: ../../tutorial/get-continuous-waveform.rst:9 31 | msgid "All times in HinetPy and Hi-net website are in JST time (GMT+0900)." 32 | msgstr "HinetPy和Hi-net网站中的所有时间都是日本标准时间(东九区,GMT+0900)。" 33 | 34 | #: ../../tutorial/get-continuous-waveform.rst:12 35 | msgid "Basic Usage" 36 | msgstr "基本用法" 37 | 38 | #: ../../tutorial/get-continuous-waveform.rst:14 39 | msgid "" 40 | "Request 20 minutes data since 2010-01-01T00:00 (GMT+0900) from Hi-net " 41 | "network:" 42 | msgstr "申请Hi-net台网从2010-01-01T00:00 (GMT+0900)开始的20分钟的数据:" 43 | 44 | #: ../../tutorial/get-continuous-waveform.rst:27 45 | msgid "" 46 | ":meth:`~HinetPy.client.Client.get_continuous_waveform` also supports ``starttime`` " 47 | "in other common used formats:" 48 | msgstr ":meth:`~HinetPy.client.Client.get_continuous_waveform` 中 ``starttime`` 还可以用其他常见格式:" 49 | 50 | #: ../../tutorial/get-continuous-waveform.rst:33 51 | msgid "" 52 | "and :py:class:`datetime.datetime` to allow users manipulate datetimes in " 53 | "a more flexible way." 54 | msgstr "并且 :py:class:`datetime.datetime` 允许用户更灵活地操作日期和时间:" 55 | 56 | #: ../../tutorial/get-continuous-waveform.rst:40 57 | msgid "Now we get:" 58 | msgstr "现在我们得到了:" 59 | 60 | #: ../../tutorial/get-continuous-waveform.rst:42 61 | msgid "" 62 | "``0101_201001010000_20.cnt``: waveform data in win32 format, default name" 63 | " format is ``CODE_YYYYmmddHHMM_LENGTH.cnt``" 64 | msgstr "" 65 | "``0101_201001010000_20.cnt``: win32格式的波形数据,默认文件名格式为 s " 66 | "``CODE_YYYYmmddHHMM_LENGTH.cnt``" 67 | 68 | #: ../../tutorial/get-continuous-waveform.rst:43 69 | msgid "" 70 | "``0101_20100101.ch``: ctable (aka channel table, similar to instrument " 71 | "response file), default name format is ``CODE_YYYYmmdd.ch``." 72 | msgstr "" 73 | "``0101_20100101.ch``: ctable数据(即通道表,类似于仪器响应文件),默认文件名格式为 " 74 | "``CODE_YYYYmmdd.ch`` 。" 75 | 76 | #: ../../tutorial/get-continuous-waveform.rst:48 77 | msgid "Hi-net sets three limitations for data request:" 78 | msgstr "Hi-net对数据申请有三个限制:" 79 | 80 | #: ../../tutorial/get-continuous-waveform.rst:50 81 | msgid "Record_Length <= 60 min" 82 | msgstr "数据记录长度不超过60分钟" 83 | 84 | #: ../../tutorial/get-continuous-waveform.rst:51 85 | msgid "Number_of_channels * Record_Length <= 12000 min" 86 | msgstr "通道数目*数据记录长度不得大于12000分钟" 87 | 88 | #: ../../tutorial/get-continuous-waveform.rst:52 89 | msgid "Only the latest 150 requested data are kept" 90 | msgstr "仅保留最近150次申请的数据" 91 | 92 | #: ../../tutorial/get-continuous-waveform.rst:54 93 | msgid "" 94 | "For the example above, Hi-net has about 2350 channels, the record length " 95 | "should be no more than 5 minutes. Thus the 20-minutes long data request " 96 | "is splitted into four 5-minutes short data subrequests." 97 | msgstr "对于上面的示例,Hi-net有大约2350个通道,因而数据长度不得超过5分钟。一个20分钟长的数据请求需要被拆分成四个5分钟的子请求。" 98 | 99 | #: ../../tutorial/get-continuous-waveform.rst:59 100 | msgid "Custom way" 101 | msgstr "自定义" 102 | 103 | #: ../../tutorial/get-continuous-waveform.rst:61 104 | msgid "" 105 | "You can set custom filename for both data and ctable, and also the output" 106 | " directory." 107 | msgstr "你可以自定义数据文件和通道表的文件名,以及输出目录。" 108 | 109 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial/get-event-waveform.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2014-2019, Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2019. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: HinetPy 0.6.1\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2019-02-19 17:30-0500\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 2.6.0\n" 19 | 20 | #: ../../tutorial/get-event-waveform.rst:2 21 | msgid "Get Event Waveform" 22 | msgstr "获取事件波形" 23 | 24 | #: ../../tutorial/get-event-waveform.rst:4 25 | msgid "" 26 | "Since v0.6.0, HinetPy supports requesting event waveform data via " 27 | ":meth:`~HinetPy.client.Client.get_event_waveform`." 28 | msgstr "" 29 | "从v0.6.0开始,HinetPy可以通过 :meth:`~HinetPy.client.Client.get_event_waveform` " 30 | "申请事件波形数据。" 31 | 32 | #: ../../tutorial/get-event-waveform.rst:7 33 | msgid "" 34 | "Following is a simple example code to request waveforms of events in a " 35 | "specified time range, magnitude and depth." 36 | msgstr "下面是一个申请时间范围、震级、深度内的事件的波形的示例。" 37 | 38 | #: ../../tutorial/get-event-waveform.rst:16 39 | msgid "You can also limit events to a specified region by three ways:" 40 | msgstr "你可以用三种方式进一步限制事件的区域范围:" 41 | 42 | #: ../../tutorial/get-event-waveform.rst:18 43 | msgid "specify region code" 44 | msgstr "指定区域代码" 45 | 46 | #: ../../tutorial/get-event-waveform.rst:19 47 | msgid "specify a box region" 48 | msgstr "指定矩形区域" 49 | 50 | #: ../../tutorial/get-event-waveform.rst:20 51 | msgid "specify a circular region" 52 | msgstr "指定环形区域" 53 | 54 | #: ../../tutorial/get-event-waveform.rst:22 55 | msgid "" 56 | "See :meth:`~HinetPy.client.Client.get_event_waveform` for more available " 57 | "options." 58 | msgstr "" 59 | "更多可用选项见 :meth:`~HinetPy.client.Client.get_event_waveform`。" 60 | 61 | -------------------------------------------------------------------------------- /docs/locale/zh_CN/LC_MESSAGES/tutorial/get-started.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) Copyright 2014-2017 Dongdong Tian 3 | # This file is distributed under the same license as the HinetPy package. 4 | # FIRST AUTHOR , 2017. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: HinetPy 0.6.1\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-07-07 23:56+0800\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Generated-By: Babel 2.13.1\n" 18 | 19 | #: ../../tutorial/get-started.rst:2 20 | msgid "Get Started" 21 | msgstr "入门" 22 | 23 | #: ../../tutorial/get-started.rst:4 24 | msgid "" 25 | "For new users of Hi-net data, I highly recommand you to request and " 26 | "download waveform data from Hi-net website and try to process the data " 27 | "using win32tools. Do all the things **manually** at least one time, make " 28 | "sure that you understand the whole procedures and the unfriendness and " 29 | "limitations of Hi-net website." 30 | msgstr "" 31 | "对于Hi-net数据的新用户,强烈建议你至少一次手动从Hi-net申请并下载数据并尝试使用 win32tools 处理数据,以确保你理解Hi-" 32 | "net数据申请、下载、处理的整个流程,并了解Hi-net网站设计的不友好和诸多限制。" 33 | 34 | #: ../../tutorial/get-started.rst:9 35 | msgid "Now let's get started." 36 | msgstr "现在开始吧。" 37 | 38 | #: ../../tutorial/get-started.rst:12 39 | msgid "Start python" 40 | msgstr "启动Python" 41 | 42 | #: ../../tutorial/get-started.rst:14 43 | msgid "" 44 | "Run ``python`` (or ``ipython`` if you have it), and make sure you're " 45 | "using Python 3.8 or above::" 46 | msgstr "在终端中运行 ``python`` (或 ``ipython`` ),并确保你所使用的Python版本大于等于3.8::" 47 | 48 | #: ../../tutorial/get-started.rst:23 49 | msgid "Create a Client" 50 | msgstr "创建一个客户端" 51 | 52 | #: ../../tutorial/get-started.rst:25 53 | msgid "" 54 | "HinetPy provide a :class:`~HinetPy.client.Client` class, which provide " 55 | "several methods to help you get waveform data." 56 | msgstr "HinetPy 中的类 :class:`~HinetPy.client.Client` 提供了多个方法帮助你获取波形数据。" 57 | 58 | #: ../../tutorial/get-started.rst:33 59 | msgid "You need a Hi-net account to access Hi-net waveform data." 60 | msgstr "你需要一个Hi-net账户以获取Hi-net台网的波形数据。" 61 | 62 | #: ../../tutorial/get-started.rst:36 63 | msgid "Do checks" 64 | msgstr "做一些检查" 65 | 66 | #: ../../tutorial/get-started.rst:38 67 | msgid "" 68 | "Let our :meth:`~HinetPy.client.Client.doctor` checks if everything goes " 69 | "right:" 70 | msgstr "用 :meth:`~HinetPy.client.Client.doctor` 检查是否一切正常:" 71 | 72 | #: ../../tutorial/get-started.rst:46 73 | msgid "" 74 | "Congratulations! You're using the latest version of HinetPy, and the Hi-" 75 | "net web service is NOT updated since the release of HinetPy, which means " 76 | "HinetPy is still working. And you have ``catwin32`` and ``win2sac_32`` in" 77 | " your PATH. Everything seems OK." 78 | msgstr "" 79 | "恭喜你!你正在使用HinetPy的最新版本,且Hi-" 80 | "net网站在这个版本HinetPy发布之后没有再更新,这意味着HinetPy依然可以正常工作。并且,``catwin32`` 和 " 81 | "``win2sac_32`` 在你的PATH中。一切看起来都正常。" 82 | 83 | #: ../../tutorial/get-started.rst:52 84 | msgid "Network Codes" 85 | msgstr "台网代码" 86 | 87 | #: ../../tutorial/get-started.rst:54 88 | msgid "" 89 | "Hi-net website provide seismic waveform data from several organizations " 90 | "and networks, e.g. Hi-net, F-net and V-net. Each network has a unique " 91 | "network code. In order to request waveform data from specified network, " 92 | "you need to know the network code. See " 93 | ":meth:`~HinetPy.client.Client.info` for details." 94 | msgstr "" 95 | "Hi-net网站提供了来自于多个组织或台网的地震波形数据,比如Hi-net、F-net和V-" 96 | "net。每个台网有唯一的台网代码。为了申请指定台网的波形数据,你必须首先知道台网代码。使用 " 97 | ":meth:`~HinetPy.client.Client.info` 以了解更多信息。" 98 | 99 | #: ../../tutorial/get-started.rst:78 100 | msgid "" 101 | "Now we know Hi-net starts from 2004-04-01 and has a total number of 2336 " 102 | "channels (about 780 stations)." 103 | msgstr "现在我们知道Hi-net开始于2004-04-01,总共有2336个通道(约780个台站)。" 104 | 105 | #: ../../tutorial/get-started.rst:83 106 | msgid "" 107 | "Users are highly recommended to use `FnetPy " 108 | "`_ if they need F-net data, since " 109 | "HinetPy cannot deal with F-net instrumental responses correctly." 110 | msgstr "" 111 | "强烈建议Fnet用户使用 `FnetPy `_ 获取Fnet数据" 112 | ",因而HinetPy无法正确处理F-net的仪器响应。" 113 | 114 | #: ../../tutorial/get-started.rst:88 115 | msgid "Stations" 116 | msgstr "台站" 117 | 118 | #: ../../tutorial/get-started.rst:90 119 | msgid "" 120 | "If you want, you can have a quick view of stations of Hi-net and F-net " 121 | "(Only these two networks are supported). See " 122 | ":meth:`~HinetPy.client.Client.get_station_list` for details." 123 | msgstr "" 124 | "你可以调用 :meth:`~HinetPy.client.Client.get_station_list` 以查看Hi-net和F-" 125 | "net台网的台站信息(目前仅支持查看这两个台网的台站信息)。" 126 | 127 | #: ../../tutorial/get-started.rst:105 128 | msgid "" 129 | "Hi-net/F-net has a lot of stations. If you only need a few of them, you " 130 | "can select the stations you want. Hi-net website also provide a web " 131 | "interface to do that, which is prefered for most cases. If you want to " 132 | "dynamically select stations in your script, you can try " 133 | ":meth:`~HinetPy.client.Client.select_stations`." 134 | msgstr "" 135 | "Hi-net/F-net有很多台。如果你只需要申请其中某些台站的数据,你可以选择你需要的台站。Hi-" 136 | "net网站提供了一个网页界面以筛选台站,通常建议值接使用这一网页界面。如果你想要在申请的过程中动态选择台站,你可以使用 " 137 | ":meth:`~HinetPy.client.Client.select_stations` 。" 138 | 139 | -------------------------------------------------------------------------------- /docs/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | .. toctree:: 5 | :maxdepth: 3 6 | 7 | tutorial/get-started 8 | tutorial/get-continuous-waveform 9 | tutorial/get-event-waveform 10 | tutorial/conversion 11 | tutorial/get-catalog 12 | -------------------------------------------------------------------------------- /docs/tutorial/conversion.rst: -------------------------------------------------------------------------------- 1 | Data conversion 2 | =============== 3 | 4 | Hi-net provide waveform data in win32 format and instrument responses in a channel 5 | table. :mod:`~HinetPy.win32` can convert them into SAC and SAC polezero formats. 6 | 7 | >>> from HinetPy import win32 8 | >>> data = "0101_201001010000_20.cnt" 9 | >>> ctable = "0101_20100101.ch" 10 | 11 | Extract Waveform Data 12 | --------------------- 13 | 14 | Extract waveform data of all channels as SAC format. 15 | 16 | >>> win32.extract_sac(data, ctable) 17 | 18 | .. important:: 19 | 20 | The SAC files converted from win32 format are **NOT** in digital counts!!! 21 | 22 | ``win2sac_32`` automatically removes sensitivity from waveforms and 23 | multipy by 1.0e9. Thus, the SAC files are velocity in nm/s or 24 | accelaration in nm/s/s. 25 | 26 | The SAC files have a default filename ``STATION.COMPONENT.SAC`` (e.g. ``N.NABC.U.SAC``). 27 | You can specify another SAC suffix and a different output directory. 28 | 29 | >>> win32.extract_sac(data, ctable, suffix="", outdir="SAC") 30 | 31 | If you want to extract only a small subset of channels, you can use ``filter_by_id``, 32 | ``filter_by_name`` and/or ``filter_by_component`` to filter the channels. 33 | They accept a list of string or a string contains wildcard. 34 | 35 | >>> # extract 3 channles by id 36 | >>> win32.extract_sac(data, ctable, filter_by_id=["3e83", "3e84", "3e85"]) 37 | >>> # extract all channels whose name match 'N.NA*' 38 | >>> win32.extract_sac(data, ctable, filter_by_name="N.NA*") 39 | >>> # extract vertical(U) component channels whose name match 'N.NA*' 40 | >>> win32.extract_sac(data, ctable, filter_by_name="N.NA*", filter_by_component="U") 41 | 42 | Extract PZ 43 | ---------- 44 | 45 | :meth:`~HinetPy.win32.extract_sacpz` can convert instrumental responses 46 | from Hi-net's channel table to SAC PZ format. 47 | 48 | .. warning:: 49 | 50 | This function works for Hi-net network only. 51 | 52 | F-net data users are highly recommended to use `FnetPy `_ 53 | to request waveform data in SEED format and extract instrumental responses 54 | in RESP or PZ format from SEED files. 55 | 56 | Extract information of all channels as SACPZ file: 57 | 58 | >>> win32.extract_sacpz(ctable) 59 | 60 | The SACPZ file has a default name ``STATION.COMPONENT.SAC_PZ`` (e.g. ``N.NABC.U.SAC_PZ``). 61 | You can specify another SACPZ suffix and a different output directory. 62 | 63 | >>> win32.extract_sacpz(ctable, suffix="SACPZ", outdir="PZ/") 64 | 65 | If you want to extract only a small subset of channels, you can use ``filter_by_id``, 66 | ``filter_by_name`` and/or ``filter_by_component`` to filter the channels. 67 | They accept a list of string or a string contains wildcard. 68 | 69 | >>> # extract 3 channles by id 70 | >>> win32.extract_sacpz(ctable, filter_by_id=["3e83", "3e84", "3e85"]) 71 | >>> # extract all channels whose name match 'N.NA*' 72 | >>> win32.extract_sacpz(ctable, filter_by_name="N.NA*") 73 | >>> # extract vertical(U) component channels whose name match 'N.NA*' 74 | >>> win32.extract_sacpz(ctable, filter_by_name="N.NA*", filter_by_component="U") 75 | 76 | .. seealso:: 77 | 78 | 1. `Response of Observation Equipment `_ 79 | 2. `Hi-net FAQ Q08 `_ 80 | 81 | .. _NIED F-net: http://www.fnet.bosai.go.jp/top.php 82 | -------------------------------------------------------------------------------- /docs/tutorial/get-catalog.rst: -------------------------------------------------------------------------------- 1 | Get Catalog 2 | ============ 3 | 4 | Get arrival time catalog 5 | ------------------------ 6 | 7 | Hi-net provide JMA arrivaltime data for downloading. 8 | 9 | >>> from HinetPy import Client 10 | >>> from datetime import datetime 11 | >>> client = Client("username", "password") 12 | >>> startdate = datetime(2010, 1, 1) 13 | >>> client.get_arrivaltime(startdate, 5) 14 | 'measure_20100101_5.txt' 15 | 16 | Get focal mechanism catalog 17 | --------------------------- 18 | 19 | Hi-net provide JMA focal mechanism catalog for downloading. 20 | 21 | >>> from HinetPy import Client 22 | >>> from datetime import datetime 23 | >>> client = Client("username", "password") 24 | >>> startdate = datetime(2010, 1, 1) 25 | >>> client.get_focalmechanism(startdate, 5) 26 | 'mecha_20100101_5.txt' 27 | -------------------------------------------------------------------------------- /docs/tutorial/get-continuous-waveform.rst: -------------------------------------------------------------------------------- 1 | Get continuous waveform 2 | ======================= 3 | 4 | This tutorial shows how to use :meth:`~HinetPy.client.Client.get_continuous_waveform` 5 | to request continuous waveform data from Hi-net in different ways. 6 | 7 | .. note:: 8 | 9 | All times in HinetPy and Hi-net website are in JST time (GMT+0900). 10 | 11 | Basic Usage 12 | ----------- 13 | 14 | Request 20 minutes data since 2010-01-01T00:00 (GMT+0900) from Hi-net network: 15 | 16 | >>> from HinetPy import Client 17 | >>> client = Client("username", "password") 18 | >>> data, ctable = client.get_continuous_waveform("0101", "201001010000", 20) 19 | [2017-03-11 17:46:20] INFO: 2010-01-01 00:00 ~20 20 | [2017-03-11 17:46:20] INFO: [1/4] => 2010-01-01 00:00 ~5 21 | [2017-03-11 17:46:41] INFO: [2/4] => 2010-01-01 00:05 ~5 22 | [2017-03-11 17:46:50] INFO: [3/4] => 2010-01-01 00:10 ~5 23 | [2017-03-11 17:47:04] INFO: [4/4] => 2010-01-01 00:15 ~5 24 | >>> ls 25 | 0101_201001010000_20.cnt 0101_20100101.ch 26 | 27 | :meth:`~HinetPy.client.Client.get_continuous_waveform` also supports ``starttime`` 28 | in other common used formats: 29 | 30 | >>> data, ctable = client.get_continuous_waveform("0101", "2010-01-01T00:00", 20) 31 | >>> data, ctable = client.get_continuous_waveform("0101", "2010-01-01 00:00", 20) 32 | 33 | and :py:class:`datetime.datetime` to allow users manipulate datetimes in a 34 | more flexible way. 35 | 36 | >>> from datetime import datetime 37 | >>> starttime = datetime(2010, 1, 1, 0, 0) # JST time 38 | >>> data, ctable = client.get_continuous_waveform("0101", starttime, 20) 39 | 40 | Now we get: 41 | 42 | 1. ``0101_201001010000_20.cnt``: waveform data in win32 format, default name format is ``CODE_YYYYmmddHHMM_LENGTH.cnt`` 43 | 2. ``0101_20100101.ch``: ctable (aka channel table, similar to instrument response file), 44 | default name format is ``CODE_YYYYmmdd.ch``. 45 | 46 | .. note:: 47 | 48 | Hi-net sets three limitations for data request: 49 | 50 | 1. Record_Length <= 60 min 51 | 2. Number_of_channels * Record_Length <= 12000 min 52 | 3. Only the latest 150 requested data are kept 53 | 54 | For the example above, Hi-net has about 2350 channels, the record length 55 | should be no more than 5 minutes. Thus the 20-minutes long data request is 56 | splitted into four 5-minutes short data subrequests. 57 | 58 | Custom way 59 | ---------- 60 | 61 | You can set custom filename for both data and ctable, and also the output 62 | directory. 63 | 64 | >>> from HinetPy import Client 65 | >>> from datetime import datetime 66 | >>> client = Client("username", "password") 67 | >>> starttime = datetime(2010, 1, 1, 0, 0) # JST time 68 | >>> data, ctable = client.get_continuous_waveform( 69 | ... "0101", 70 | ... starttime, 71 | ... 20, 72 | ... data="201001010000.cnt", 73 | ... ctable="0101.ch", 74 | ... outdir="201001010000", 75 | ... ) 76 | [2017-03-11 17:46:20] INFO: 2010-01-01 00:00 ~20 77 | [2017-03-11 17:46:20] INFO: [1/4] => 2010-01-01 00:00 ~5 78 | [2017-03-11 17:46:41] INFO: [2/4] => 2010-01-01 00:05 ~5 79 | [2017-03-11 17:46:50] INFO: [3/4] => 2010-01-01 00:10 ~5 80 | [2017-03-11 17:47:04] INFO: [4/4] => 2010-01-01 00:15 ~5 81 | >>> # You should see a directory "201001010000" with two files 82 | >>> # "0101.ch" and "201001010000.cnt" inside. 83 | -------------------------------------------------------------------------------- /docs/tutorial/get-event-waveform.rst: -------------------------------------------------------------------------------- 1 | Get Event Waveform 2 | ================== 3 | 4 | Since v0.6.0, HinetPy supports requesting event waveform data via 5 | :meth:`~HinetPy.client.Client.get_event_waveform`. 6 | 7 | Following is a simple example code to request waveforms of events 8 | in a specified time range, magnitude and depth. 9 | 10 | >>> from HinetPy import Client 11 | >>> client = Client("username", "password") 12 | >>> client.get_event_waveform( 13 | ... "201001010000", 14 | ... "201001020000", 15 | ... minmagnitude=4.0, 16 | ... maxmagnitude=7.0, 17 | ... mindepth=0, 18 | ... maxdepth=70, 19 | ... ) 20 | 21 | You can also limit events to a specified region by three ways: 22 | 23 | - specify region code 24 | - specify a box region 25 | - specify a circular region 26 | 27 | See :meth:`~HinetPy.client.Client.get_event_waveform` for more available options. 28 | -------------------------------------------------------------------------------- /docs/tutorial/get-started.rst: -------------------------------------------------------------------------------- 1 | Get Started 2 | =========== 3 | 4 | For new users of Hi-net data, I highly recommand you to request and download 5 | waveform data from Hi-net website and try to process the data using win32tools. 6 | Do all the things **manually** at least one time, make sure that you understand 7 | the whole procedures and the unfriendness and limitations of Hi-net website. 8 | 9 | Now let's get started. 10 | 11 | Start python 12 | ------------ 13 | 14 | Run ``python`` (or ``ipython`` if you have it), and make sure you're using 15 | Python 3.8 or above:: 16 | 17 | $ python 18 | Python 3.11.6 | packaged by conda-forge | (main, Oct 3 2023, 10:40:35) [GCC 12.3.0] on linux 19 | Type "help", "copyright", "credits" or "license" for more information. 20 | >>> 21 | 22 | Create a Client 23 | --------------- 24 | 25 | HinetPy provide a :class:`~HinetPy.client.Client` class, which provide several 26 | methods to help you get waveform data. 27 | 28 | >>> from HinetPy import Client 29 | >>> client = Client("username", "password") # use your own account. 30 | 31 | .. note:: 32 | 33 | You need a Hi-net account to access Hi-net waveform data. 34 | 35 | Do checks 36 | --------- 37 | 38 | Let our :meth:`~HinetPy.client.Client.doctor` checks if everything goes right: 39 | 40 | >>> client.doctor() 41 | [2019-06-14 16:11:47] INFO: You're using the latest release (v0.6.3). 42 | [2019-06-14 16:11:46] INFO: Hi-net web service is NOT updated. 43 | [2019-06-14 16:11:47] INFO: catwin32: /home/user/bin/catwin32. 44 | [2019-06-14 16:11:47] INFO: win2sac_32: /home/user/bin/win2sac_32. 45 | 46 | Congratulations! You're using the latest version of HinetPy, and the Hi-net 47 | web service is NOT updated since the release of HinetPy, which means HinetPy 48 | is still working. And you have ``catwin32`` and ``win2sac_32`` in your PATH. 49 | Everything seems OK. 50 | 51 | Network Codes 52 | ------------- 53 | 54 | Hi-net website provide seismic waveform data from several organizations and 55 | networks, e.g. Hi-net, F-net and V-net. Each network has a unique network code. 56 | In order to request waveform data from specified network, you need to know 57 | the network code. See :meth:`~HinetPy.client.Client.info` for details. 58 | 59 | >>> client.info() 60 | 0101 : NIED Hi-net 61 | 0103 : NIED F-net (broadband) 62 | 0103A : NIED F-net (strong motion) 63 | 010501 : NIED V-net (Tokachidake) 64 | 010502 : NIED V-net (Tarumaesan) 65 | ... 66 | 0701 : Tokyo Metropolitan Government 67 | 0702 : Hot Spring Research Institute of Kanagawa Prefecture 68 | 0703 : Aomori Prefectural Government 69 | 0705 : Shizuoka Prefectural Government 70 | 0801 : ADEP 71 | >>> client.info("0101") # get more information about NIED Hi-net (0101) 72 | == Information of Network 0101 == 73 | Name: NIED Hi-net 74 | Homepage: http://www.hinet.bosai.go.jp/ 75 | Starttime: 20040401 76 | No. of channels: 2336 77 | 78 | Now we know Hi-net starts from 2004-04-01 and has a total number of 79 | 2336 channels (about 780 stations). 80 | 81 | .. note:: 82 | 83 | Users are highly recommended to use `FnetPy `_ 84 | if they need F-net data, since HinetPy cannot deal with F-net instrumental 85 | responses correctly. 86 | 87 | Stations 88 | -------- 89 | 90 | If you want, you can have a quick view of stations of Hi-net and F-net 91 | (Only these two networks are supported). 92 | See :meth:`~HinetPy.client.Client.get_station_list` for details. 93 | 94 | >>> stations = client.get_station_list("0101") 95 | >>> for station in stations: 96 | ... print(station) 97 | ... 98 | 0101 N.WNNH 45.4883 141.885 -159.06 99 | 0101 N.SFNH 45.3346 142.1185 -81.6 100 | 0101 N.WNWH 45.2531 141.6334 -130.6 101 | 0101 N.WNEH 45.2303 141.8806 -174.6 102 | 0101 N.SFSH 45.2163 142.2254 -96.6 103 | ... 104 | 105 | Hi-net/F-net has a lot of stations. If you only need a few of them, you can 106 | select the stations you want. Hi-net website also provide a web interface to 107 | do that, which is prefered for most cases. If you want to dynamically select 108 | stations in your script, you can try 109 | :meth:`~HinetPy.client.Client.select_stations`. 110 | 111 | >>> # select only two stations of Hi-net if you know the station names 112 | >>> client.select_stations("0101", ["N.AAKH", "N.ABNH"]) 113 | >>> 114 | >>> # select Hi-net stations in a box region 115 | >>> client.select_stations( 116 | ... "0101", minlatitude=36, maxlatitude=50, minlongitude=140, maxlongitude=150 117 | ... ) 118 | >>> 119 | >>> # select Hi-net stations in a circular region 120 | >>> client.select_stations("0101", latitude=36, longitude=139, minradius=0, maxradius=3) 121 | >>> # select all Hi-net stations 122 | >>> client.select_stations("0101") 123 | -------------------------------------------------------------------------------- /paper/paper.bib: -------------------------------------------------------------------------------- 1 | @article{Obara2005, 2 | title={{A densely distributed high-sensitivity seismograph network in Japan: Hi-net by National Research Institute for Earth Science and Disaster Prevention}}, 3 | author={Obara, Kazushige and Kasahara, Keiji and Hori, Sadaki and Okada, Yoshimitsu}, 4 | journal={Review of Scientific Instruments}, 5 | volume={76}, 6 | number={2}, 7 | pages={021301}, 8 | year={2005}, 9 | month=feb, 10 | DOI={10.1063/1.1854197} 11 | } 12 | 13 | @article{Ishii2005, 14 | title={{Extent, duration and speed of the 2004 Sumatra–Andaman earthquake imaged by the Hi-Net array}}, 15 | author={Ishii, Miaki and Shearer, Peter M. and Houston, Heidi and Vidale, John E.}, 16 | journal={Nature}, 17 | volume={435}, 18 | number={7044}, 19 | pages={933–936}, 20 | year={2005}, 21 | month=jun, 22 | DOI={10.1038/nature03675} 23 | } 24 | 25 | @article{Peng2007, 26 | title={{Seismicity rate immediately before and after main shock rupture from high‐frequency waveforms in Japan}}, 27 | author={Peng, Zhigang and Vidale, John E. and Ishii, Miaki and Helmstetter, Agnes}, 28 | journal={Journal of Geophysical Research: Solid Earth}, 29 | volume={112}, 30 | number={B3}, 31 | pages={2006JB004386}, 32 | year={2007}, 33 | month=mar, 34 | DOI={10.1029/2006JB004386}, 35 | } 36 | 37 | @article{Okada2014, 38 | title={{Recent progress of seismic observation networks in Japan —Hi-net, F-net, K-NET and KiK-net—}}, 39 | author={Okada, Yoshimitsu and Kasahara, Keiji and Hori, Sadaki and Obara, Kazushige and Sekiguchi, Shoji and Fujiwara, Hiroyuki and Yamamoto, Akira}, 40 | journal={Earth, Planets and Space}, 41 | volume={56}, 42 | number={8}, 43 | pages={xv–xxviii}, 44 | year={2014}, 45 | month=jun, 46 | DOI={10.1186/BF03353076}, 47 | } 48 | 49 | @article{ObsPy2015, 50 | title={{ObsPy: a bridge for seismology into the scientific Python ecosystem}}, 51 | author={Krischer, Lion and Megies, Tobias and Barsch, Robert and Beyreuther, Moritz and Lecocq, Thomas and Caudron, Corentin and Wassermann, Joachim}, 52 | journal={Computational Science & Discovery}, 53 | volume={8}, 54 | number={1}, 55 | pages={014003}, 56 | year={2015}, 57 | month=may, 58 | DOI={10.1088/1749-4699/8/1/014003}, 59 | } 60 | 61 | @article{Yee2014, 62 | title={{Regionally heterogeneous uppermost inner core observed with Hi‐net array}}, 63 | journal={Journal of Geophysical Research: Solid Earth}, 64 | author={Yee, Tae‐Gyu and Rhie, Junkee and Tkalčić, Hrvoje}, 65 | volume={119}, 66 | number={10}, 67 | pages={7823–7845}, 68 | year={2014}, 69 | month=oct, 70 | DOI={10.1002/2014JB011341}, 71 | } 72 | @article{Niu2005, 73 | title={{Mapping the subducting Pacific slab beneath southwest Japan with Hi-net receiver functions}}, 74 | journal={Earth and Planetary Science Letters}, 75 | author={Niu, Fenglin and Levander, Alan and Ham, Sangwon and Obayashi, Masayuki}, 76 | volume={239}, 77 | number={1–2}, 78 | pages={9–17}, 79 | year={2005}, 80 | month=oct, 81 | DOI={10.1016/j.epsl.2005.08.009}, 82 | } 83 | 84 | @article{Tian2017, 85 | title={{Seismological evidence for a localized mushy zone at the Earth's inner core boundary}}, 86 | journal={Nature Communications}, 87 | author={Tian, Dongdong and Wen, Lianxing}, 88 | volume={8}, 89 | pages={165}, 90 | number={1}, 91 | year={2017}, 92 | month=aug, 93 | DOI={10.1038/s41467-017-00229-9}, 94 | } 95 | -------------------------------------------------------------------------------- /paper/paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'HinetPy: A Python package for accessing and processing NIED Hi-net seismic data' 3 | tags: 4 | - Python 5 | - geophysics 6 | - seismology 7 | authors: 8 | - name: Dongdong Tian 9 | orcid: 0000-0001-7967-1197 10 | affiliation: 1 11 | affiliations: 12 | - name: Hubei Subsurface Multi-scale Imaging Key Laboratory, School of Geophysics and Geomatics, China University of Geosciences, Wuhan 430074, China 13 | index: 1 14 | date: 3 April 2024 15 | bibliography: paper.bib 16 | --- 17 | 18 | # Summary 19 | 20 | HinetPy is a Python package designed for researchers working with seismic data from the 21 | National Research Institute for Earth Science and Disaster Resilience (NIED) Hi-net 22 | (High-sensitivity seismograph network) in Japan. The seismic network comprises approximately 23 | 800 stations with high-quality seismic data. Accessing and processing the data can be 24 | challenging due to the limited functionality of the web UI and backend data server. 25 | Additionally, the seismic data is stored in a non-standard format, which adds an extra 26 | layer of complexity. HinetPy solves these challenges by offering a user-friendly interface 27 | for accessing seismic data from NIED Hi-net and converting it to commonly used data 28 | formats. It streamlines the workflow for seismologists, enabling them to more effectively 29 | utilize this valuable dataset. 30 | 31 | # Statement of need 32 | 33 | The National Research Institute for Earth Science and Disaster Resilience (NIED) operates 34 | and maintains NIED Hi-net, a nationwide high-sensitivity seismograph network in Japan. 35 | Since its establishment in October 2000, NIED Hi-net has grown to include approximately 36 | 800 seismic stations equipped with three-component short-period seismometers [@Obara2005; @Okada2014]. 37 | The NIED Hi-net website ([https://www.hinet.bosai.go.jp/](https://www.hinet.bosai.go.jp/)) 38 | provides access to high-quality seismic data from 2004 onwards, including data from 39 | other seismic networks such as F-net, S-net, V-net, and more. The NIED Hi-net data has 40 | been widely used in various research from the study of earthquakes [e.g., @Ishii2005; @Peng2007] 41 | to the structure of the Earth's deep interior [e.g., @Niu2005; @Yee2014; @Tian2017]. 42 | Despite the value of the data provided by NIED Hi-net, accessing and processing it can be challenging. 43 | 44 | ## Challenges in accessing NIED Hi-net data 45 | 46 | The NIED Hi-net data is available for free through the NIED Hi-net website after users 47 | register for an account. However, accessing them can still be challenging. While most seismic 48 | data centers have transitioned to standard FDSN web services 49 | ([https://www.fdsn.org/webservices/](https://www.fdsn.org/webservices/)) in recent years, 50 | allowing users to request seismic data using open-source tools like ObsPy [@ObsPy2015], 51 | NIED Hi-net has not yet upgraded to adopt these services. To request data 52 | from the NIED Hi-net website, users must log in and click many buttons manually. 53 | It is important to note that the NIED Hi-net website has limitations on the data 54 | size and length in a single request. Specifically, the record length of a single channel 55 | cannot exceed 60 minutes, and the total record length of 56 | all channels cannot exceed 12,000 minutes. Considering that NIED Hi-net comprises about 800 seismic 57 | stations and 2,400 channels (3 channels per station), the record length in a single 58 | request must not exceed 5 minutes. If users require 30 minutes of data, they must divide the 59 | time range into six subranges and submit six separate requests. The NIED Hi-net website 60 | does not allow users to post multiple data requests simultaneously. Therefore, to obtain 61 | the requested data, users must post a request, wait for the data to be prepared, and then 62 | post subsequent requests. After all data is ready, users must manually download the files 63 | and combine them into a single file. The entire process can be time-consuming and cumbersome. 64 | 65 | ## Challenges in processing NIED Hi-net data 66 | 67 | NIED Hi-net stores seismic data in a non-standard format called WIN32, accompanied by a 68 | 'channels table' text file containing metadata for each channel. Most seismic data processing 69 | software, such as ObsPy, cannot directly use these non-standard formats. Therefore, additional 70 | processing is required to convert the data to commonly used formats, which poses challenges 71 | for researchers. Although NIED Hi-net provides a set of commands in their win32tools package 72 | to process WIN32 data and convert to the SAC format, there are currently no tools available 73 | to convert the channels table to a more commonly used format, such as the SAC polezero file format. 74 | This limitation hinders the broader utilization of NIED Hi-net data. 75 | 76 | # HinetPy for easy data accessing and processing 77 | 78 | HinetPy is designed to address specific challenges with accessing and processing 79 | NIED Hi-net data through a user-friendly interface. It primarily offers two key components: 80 | the `Client` class for data accessing and the `win32` module for data processing. 81 | 82 | The `Client` class utilizes the popular HTTP library [Requests](https://github.com/psf/requests) 83 | to handle user authentication, data requests, status queries, and downloads. This simplifies 84 | the process of accessing NIED Hi-net data, allowing users to access data without any 85 | manual operations on the Hi-net website. 86 | 87 | The `win32` module provides several functions for processing WIN32 data, including: 88 | 89 | - Merging multiple small WIN32 data files into a single large WIN32 file. 90 | - Converting data from WIN32 format to SAC format. 91 | - Creating instrumental responses in SAC polezero format. 92 | 93 | Internally, the `win32` module currently relies on the `catwin32` and `win2sac_32` commands 94 | from the NIED win32tools package for WIN32 data processing. Therefore, the win32tools package 95 | (at least the two required commands) must be installed before using HinetPy. 96 | 97 | This is an example demonstrating how to request 20 minutes of waveform data of the Hi-net 98 | network starting at 2010-01-01T00:00 (JST, GMT+0900), convert the data to SAC format 99 | and extract SAC polezero files: 100 | ```python 101 | from HinetPy import Client, win32 102 | 103 | # You need to register a Hi-net account first 104 | client = Client("username", "password") 105 | 106 | # Let's try to request 20-minute data of the Hi-net network (with an internal 107 | # network code of '0101') starting at 2010-01-01T00:00 (JST, GMT+0900) 108 | data, ctable = client.get_continuous_waveform("0101", "201001010000", 20) 109 | 110 | # The request and download process usually takes a few minutes. 111 | # Be patient... 112 | # Now you can see the data and channels table in your working directory 113 | # Waveform data (in win32 format) : 0101_201001010000_20.cnt 114 | # Channels table (plaintext file) : 0101_20100101.ch 115 | 116 | # Convert data from win32 format to SAC format 117 | win32.extract_sac(data, ctable) 118 | # Extract instrumental responses and save as SAC polezero files 119 | win32.extract_sacpz(ctable) 120 | 121 | # Now you can see several SAC and SAC_PZ files in your working directory. 122 | # 123 | # N.NGUH.E.SAC ... 124 | # N.NGUH.E.SAC_PZ ... 125 | ``` 126 | 127 | `"0101"` is the internal network code of the Hi-net network. The full list of supported 128 | seismic networks and their internal network codes can be obtained via `client.info()`. 129 | 130 | # Key features 131 | 132 | The key features of HinetPy are: 133 | 134 | 1. Facilitates easy access to NIED Hi-net seismic data, including continuous/event waveform 135 | data and event catalogs. 136 | 2. Supports multiple seismic networks (e.g., F-net, S-net, MeSO-net and more in addition 137 | to Hi-net) in Japan. 138 | 3. Selects a subset of stations based on geographical location or station name (Supports 139 | Hi-net, F-net, S-net and MeSO-net only). 140 | 4. Converts waveform data to SAC format and instrumental responses to SAC polezero files. 141 | 5. Speeds up the downloading and processing workflow via the use of multithreading. 142 | 143 | # Important notes on the use of NIED Hi-net data 144 | 145 | 1. Users must register an account on the NIED Hi-net website for accessing the data and 146 | renew the account annually. 147 | 2. Users should report their research results using NIED Hi-net data to NIED. 148 | 3. Redistribution of any NIED Hi-net data is prohibited. 149 | 150 | # Acknowledgments 151 | 152 | The HinetPy package was first developed in 2013 by the author during the time as a graduate 153 | student at the University of Science and Technology of China (USTC). It was later maintained 154 | during the author's postdoctoral work at Michigan State University (MSU) and as a faculty 155 | member at the China University of Geosciences, Wuhan. The authors would like to thank 156 | users who report bugs and request features. The author is supported by 157 | the National Natural Science Foundation of China under grant NSFC42274122, 158 | the “CUG Scholar” Scientific Research Funds at China University of Geosciences (Wuhan) (Project No. 2022012), 159 | and the Fundamental Research Funds for the Central Universities, China University of Geosciences (Wuhan) (No. CUG230604). 160 | 161 | # References 162 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=64", "setuptools_scm[toml]>=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "HinetPy" 7 | description = "A Python package for accessing and processing NIED Hi-net seismic data" 8 | readme = "README.rst" 9 | requires-python = ">=3.8" 10 | authors = [{name = "Dongdong Tian", email = "seisman.info@gmail.com"}] 11 | keywords = ["seismology", "NIED", "Hi-net", "waveform"] 12 | classifiers = [ 13 | "Development Status :: 4 - Beta", 14 | "Intended Audience :: Science/Research", 15 | "Intended Audience :: Education", 16 | "License :: OSI Approved :: MIT License", 17 | "Operating System :: POSIX :: Linux", 18 | "Operating System :: MacOS", 19 | "Programming Language :: Python", 20 | "Programming Language :: Python :: 3.8", 21 | "Programming Language :: Python :: 3.9", 22 | "Programming Language :: Python :: 3.10", 23 | "Programming Language :: Python :: 3.11", 24 | "Programming Language :: Python :: 3.12", 25 | "Programming Language :: Python :: 3 :: Only", 26 | "Topic :: Internet :: WWW/HTTP", 27 | "Topic :: Scientific/Engineering :: Physics", 28 | "Topic :: Utilities", 29 | ] 30 | dependencies = ["certifi", "packaging", "requests", "urllib3"] 31 | dynamic = ["version"] 32 | 33 | [project.urls] 34 | homepage = "https://seisman.github.io/HinetPy/" 35 | documentation = "https://seisman.github.io/HinetPy/" 36 | repository = "https://github.com/seisman/HinetPy" 37 | 38 | [tool.setuptools] 39 | license-files = ["LICENSE"] 40 | 41 | [tool.setuptools.packages.find] 42 | include = ["HinetPy*"] 43 | exclude = ["docs", "tests", "paper"] 44 | 45 | [tool.setuptools_scm] 46 | local_scheme = "node-and-date" 47 | fallback_version = "999.999.999+unknown" 48 | 49 | # All the ruff settings are directly copied from the PyGMT project. 50 | [tool.ruff] 51 | line-length = 88 52 | output-format = "full" 53 | 54 | [tool.ruff.format] 55 | line-ending = "lf" 56 | docstring-code-format = true 57 | docstring-code-line-length = "dynamic" 58 | 59 | [tool.ruff.lint] 60 | select = [ 61 | "A", # flake8-builtins 62 | "B", # flake8-bugbear 63 | "BLE", # flake8-blind-except 64 | "C4", # flake8-comprehensions 65 | "E", # pycodestyle 66 | "EXE", # flake8-executable 67 | "F", # pyflakes 68 | "FA", # flake8-future-annotations 69 | "FLY", # flynt 70 | "I", # isort 71 | "ICN", # flake8-import-conventions 72 | "ISC", # flake8-implicit-str-concat 73 | "N", # pep8-naming 74 | "NPY", # numpy 75 | "PD", # pandas-vet 76 | "PERF", # perflint 77 | "PGH", # pygrep-hooks 78 | "PIE", # flake8-pie 79 | "PL", # pylint 80 | "RET", # flake8-return 81 | "RSE", # flake8-raise 82 | "RUF", # ruff-specific 83 | "S", # flake8-bandit 84 | "SIM", # flake8-simplify 85 | "TCH", # flake8-type-checking 86 | "TID", # flake8-tidy-imports 87 | "UP", # pyupgrade 88 | "W", # pycodestyle warnings 89 | "YTT", # flake8-2020 90 | ] 91 | extend-select = [ 92 | "D213", # Summary lines should be positioned on the second physical line of the docstring. 93 | "D410", # A blank line after section headings. 94 | ] 95 | ignore = [ 96 | "D200", # One-line docstring should fit on one line 97 | "D202", # No blank lines allowed after function docstring 98 | "D205", # 1 blank line required between summary line and description 99 | "D400", # First line should end with a period 100 | "D401", # First line of docstring should be in imperative mood 101 | "D412", # No blank lines allowed between a section header and its content 102 | "E501", # Avoid enforcing line-length violations 103 | "ISC001", # Single-line-implicit-string-concatenation, conflict with formatter 104 | "PD901", # Allow using the generic variable name `df` for DataFrames 105 | "PT023", # Allow using pytest marker without parentheses 106 | "PLR2004", # Allow any magic values 107 | "RET504", # Allow variable assignment and return immediately for readability 108 | "S603", # Allow method calls that initiate a subprocess without a shell 109 | "SIM117", # Allow nested `with` statements 110 | ] 111 | 112 | [tool.ruff.lint.isort] 113 | known-third-party = ["HinetPy"] 114 | 115 | [tool.ruff.lint.per-file-ignores] 116 | "__init__.py" = ["F401"] # Ignore `F401` (unused-import) in all `__init__.py` files 117 | "tests/test_*.py" = ["S101"] # Ignore `S101` (use of assert) in all tests files 118 | 119 | [tool.ruff.lint.pycodestyle] 120 | max-doc-length = 88 121 | 122 | [tool.ruff.lint.pydocstyle] 123 | # See https://docs.astral.sh/ruff/faq/#does-ruff-support-numpy-or-google-style-docstrings 124 | # for the enabled/disabled rules for the "numpy" convention. 125 | convention = "numpy" 126 | 127 | [tool.ruff.lint.pylint] 128 | max-args=10 129 | 130 | [tool.pytest.ini_options] 131 | minversion = "6.0" 132 | addopts = "--verbose --cov=HinetPy --cov-report=term-missing --cov-report=xml" 133 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # General dependencies 2 | build 3 | # Dev dependencies for testing 4 | pytest 5 | pytest-cov 6 | # Dev dependencies for code style 7 | ruff 8 | # Dev dependencies for documentation 9 | sphinx 10 | sphinx-intl 11 | sphinx_rtd_theme 12 | # Dev dependencies for static type checks 13 | mypy 14 | types-requests 15 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi 2 | packaging 3 | requests 4 | urllib3 5 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seisman/HinetPy/256df963873191fce4eed8212385ca3bdf7a5020/tests/__init__.py -------------------------------------------------------------------------------- /tests/localtest_channels.py: -------------------------------------------------------------------------------- 1 | """ 2 | Check the number of channels for each network. 3 | """ 4 | 5 | import os 6 | from datetime import datetime, timedelta 7 | 8 | from HinetPy import Client 9 | from HinetPy.header import NETWORK 10 | from HinetPy.win32 import read_ctable 11 | 12 | username = os.environ["HINET_USERNAME"] 13 | password = os.environ["HINET_PASSWORD"] 14 | client = Client(username, password) 15 | 16 | # always set one day before today as starttime 17 | starttime = datetime.today() - timedelta(days=1) 18 | for code in sorted(NETWORK.keys()): 19 | win32, chfile = client.get_continuous_waveform(code, starttime, 1) 20 | if chfile is None: 21 | continue 22 | count = len(read_ctable(chfile)) 23 | print(code, count) 24 | -------------------------------------------------------------------------------- /tests/localtest_client_multi_threads.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import datetime 3 | 4 | from HinetPy import Client 5 | 6 | username = os.environ["HINET_USERNAME"] 7 | password = os.environ["HINET_PASSWORD"] 8 | client = Client(username, password) 9 | starttime = datetime(2017, 1, 1, 0, 0) 10 | client.get_continuous_waveform("0101", starttime, 20, threads=4) 11 | -------------------------------------------------------------------------------- /tests/test_channel.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for channel. 3 | """ 4 | 5 | from HinetPy.channel import Channel 6 | 7 | 8 | def test_channel(): 9 | """ 10 | Make sure channel calculation is correct. 11 | """ 12 | chn = Channel( 13 | id="3e83", 14 | name="N.NNMH", 15 | component="U", 16 | latitude=37.2822, 17 | longitude=140.2144, 18 | unit="m/s", 19 | gain=183.20, 20 | damping=0.70, 21 | period=0.98, 22 | preamplification=0.0, 23 | lsb_value=1.023e-7, 24 | ) 25 | chn._get_polezero() 26 | assert chn.zeros == 3 27 | assert chn.poles == 2 28 | assert chn.real == -4.487989505128276 29 | assert chn.imaginary == 4.578665119846432 30 | assert chn.a0 == 0.999951325192476 31 | assert chn.sensitivity == 1790811339.198436 32 | -------------------------------------------------------------------------------- /tests/test_client.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | from datetime import date, datetime 4 | 5 | import pytest 6 | import requests 7 | from HinetPy import Client 8 | 9 | username = os.environ["HINET_USERNAME"] 10 | password = os.environ["HINET_PASSWORD"] 11 | 12 | 13 | @pytest.fixture(scope="module") 14 | def client(): 15 | client = Client(username, password) 16 | client.select_stations("0101", ["N.AAKH", "N.ABNH"]) 17 | yield client 18 | client.select_stations("0101") 19 | 20 | 21 | def test_client_init_and_login_succeed(): 22 | Client(username, password) 23 | 24 | 25 | def test_client_init_and_login_fail(): 26 | """Raise ConnectionError if requests fails.""" 27 | with pytest.raises(requests.ConnectionError): 28 | Client("anonymous", "anonymous") 29 | 30 | 31 | def test_login_after_init(): 32 | client = Client() 33 | client.login(username, password) 34 | 35 | 36 | def test_check_service_update(client): 37 | assert not client.check_service_update() 38 | 39 | 40 | def test_docter(client): 41 | client.doctor() 42 | 43 | 44 | def test_get_continuous_waveform_1(client): 45 | starttime = datetime(2010, 1, 1, 0, 0) 46 | data, ctable = client.get_continuous_waveform("0101", starttime, 9) 47 | 48 | assert data == "0101_201001010000_9.cnt" 49 | assert os.path.exists(data) 50 | os.remove(data) 51 | assert ctable == "0101_20100101.ch" 52 | assert os.path.exists(ctable) 53 | os.remove(ctable) 54 | 55 | 56 | def test_get_continuous_waveform_starttime_in_string(client): 57 | data, ctable = client.get_continuous_waveform("0101", "2010-01-01T00:00", 9) 58 | 59 | assert data == "0101_201001010000_9.cnt" 60 | assert os.path.exists(data) 61 | os.remove(data) 62 | assert ctable == "0101_20100101.ch" 63 | assert os.path.exists(ctable) 64 | os.remove(ctable) 65 | 66 | 67 | def test_get_continuous_waveform_custom_name_1(client): 68 | starttime = datetime(2010, 1, 1, 0, 0) 69 | data, ctable = client.get_continuous_waveform( 70 | "0101", starttime, 1, data="customname1.cnt", ctable="customname1.ch" 71 | ) 72 | 73 | assert data == "customname1.cnt" 74 | assert os.path.exists(data) 75 | os.remove(data) 76 | assert ctable == "customname1.ch" 77 | assert os.path.exists(ctable) 78 | os.remove(ctable) 79 | 80 | 81 | def test_get_continuous_waveform_custom_name_2(client): 82 | starttime = datetime(2010, 1, 1, 0, 0) 83 | data, ctable = client.get_continuous_waveform( 84 | "0101", 85 | starttime, 86 | 1, 87 | data="customname2/customname2.cnt", 88 | ctable="customname2/customname2.ch", 89 | ) 90 | 91 | assert data == "customname2/customname2.cnt" 92 | assert os.path.exists(data) 93 | assert ctable == "customname2/customname2.ch" 94 | assert os.path.exists(ctable) 95 | shutil.rmtree("customname2") 96 | 97 | 98 | def test_get_continuous_waveform_custom_name_3(client): 99 | starttime = datetime(2010, 1, 1, 0, 0) 100 | data, ctable = client.get_continuous_waveform( 101 | "0101", starttime, 1, outdir="customname3" 102 | ) 103 | 104 | assert data == "customname3/0101_201001010000_1.cnt" 105 | assert os.path.exists(data) 106 | assert ctable == "customname3/0101_20100101.ch" 107 | assert os.path.exists(ctable) 108 | shutil.rmtree("customname3") 109 | 110 | 111 | def test_get_continuous_waveform_custom_name_4(client): 112 | starttime = datetime(2010, 1, 1, 0, 0) 113 | data, ctable = client.get_continuous_waveform( 114 | "0101", 115 | starttime, 116 | 1, 117 | data="customname4-cnt/test.cnt", 118 | ctable="customname4-ch/test.ch", 119 | outdir="customname4-data", 120 | ) 121 | 122 | assert data == "customname4-cnt/test.cnt" 123 | assert os.path.exists(data) 124 | assert ctable == "customname4-ch/test.ch" 125 | assert os.path.exists(ctable) 126 | shutil.rmtree("customname4-cnt") 127 | shutil.rmtree("customname4-ch") 128 | 129 | 130 | def test_get_waveform_alias(client): 131 | starttime = datetime(2010, 1, 1, 0, 0) 132 | data, ctable = client.get_waveform("0101", starttime, 1) 133 | 134 | 135 | def test_get_continuous_waveform_wrong_span_1(client): 136 | starttime = datetime(2005, 1, 1, 0, 0) 137 | with pytest.raises(ValueError): 138 | client.get_continuous_waveform("0101", starttime, 0) 139 | 140 | 141 | def test_get_continuous_waveform_wrong_span_2(client): 142 | starttime = datetime(2005, 1, 1, 0, 0) 143 | with pytest.raises(ValueError): 144 | client.get_continuous_waveform("0101", starttime, -4) 145 | 146 | 147 | def test_get_continuous_waveform_wrong_span_3(client): 148 | starttime = datetime(2005, 1, 1, 0, 0) 149 | with pytest.raises(TypeError): 150 | client.get_continuous_waveform("0101", starttime, 2.5) 151 | 152 | 153 | def test_get_continuous_waveform_span_larger_than_int(client): 154 | starttime = datetime(2005, 1, 1, 0, 0) 155 | with pytest.raises(ValueError): 156 | client.get_continuous_waveform("0101", starttime, 400000) 157 | 158 | 159 | def test_get_continuous_waveform_larger_max_span(client): 160 | starttime = datetime(2010, 1, 1, 0, 0) 161 | data, ctable = client.get_continuous_waveform("0101", starttime, 10, max_span=65) 162 | assert data == "0101_201001010000_10.cnt" 163 | assert os.path.exists(data) 164 | os.remove(data) 165 | assert ctable == "0101_20100101.ch" 166 | assert os.path.exists(ctable) 167 | os.remove(ctable) 168 | 169 | 170 | def test_get_continuous_waveform_wrong_starttime(client): 171 | starttime = datetime(2001, 1, 1, 0, 0) 172 | with pytest.raises(ValueError): 173 | client.get_continuous_waveform("0101", starttime, 1) 174 | 175 | 176 | def test_get_arrivaltime_1(client): 177 | startdate = date(2010, 1, 1) 178 | data = client.get_arrivaltime(startdate, 5) 179 | assert data == "measure_20100101_5.txt" 180 | assert os.path.exists(data) 181 | os.remove(data) 182 | 183 | 184 | def test_get_arrivaltime_2(client): 185 | startdate = date(2010, 1, 1) 186 | data = client.get_arrivaltime(startdate, 5, filename="arrivaltime.txt") 187 | assert data == "arrivaltime.txt" 188 | assert os.path.exists(data) 189 | os.remove(data) 190 | 191 | 192 | def test_get_arrivaltime_use_datetime(client): 193 | startdate = datetime(2010, 1, 1) 194 | data = client.get_arrivaltime(startdate, 5) 195 | assert data == "measure_20100101_5.txt" 196 | assert os.path.exists(data) 197 | os.remove(data) 198 | 199 | 200 | def test_get_arrivaltime_startdate_in_string(client): 201 | data = client.get_arrivaltime("20100101", 5) 202 | assert data == "measure_20100101_5.txt" 203 | assert os.path.exists(data) 204 | os.remove(data) 205 | 206 | 207 | def test_get_focalmechanism_1(client): 208 | startdate = date(2010, 1, 1) 209 | data = client.get_focalmechanism(startdate, 5) 210 | assert data == "mecha_20100101_5.txt" 211 | assert os.path.exists(data) 212 | os.remove(data) 213 | 214 | 215 | def test_get_focalmachanism_2(client): 216 | startdate = date(2010, 1, 1) 217 | data = client.get_focalmechanism(startdate, 5, filename="focal.txt") 218 | assert data == "focal.txt" 219 | assert os.path.exists(data) 220 | os.remove(data) 221 | 222 | 223 | def test_get_focalmachanism_use_datetime(client): 224 | startdate = datetime(2010, 1, 1) 225 | data = client.get_focalmechanism(startdate, 5, filename="focal.txt") 226 | assert data == "focal.txt" 227 | assert os.path.exists(data) 228 | os.remove(data) 229 | 230 | 231 | def test_get_catalog_wrong_span(client): 232 | startdate = date(2010, 1, 1) 233 | with pytest.raises(ValueError): 234 | client.get_arrivaltime(startdate, 10) 235 | 236 | 237 | def test_get_event_waveform(client): 238 | client.get_event_waveform( 239 | "201001010000", 240 | "201001020000", 241 | minmagnitude=3.5, 242 | maxmagnitude=5.5, 243 | mindepth=0, 244 | maxdepth=70, 245 | minlatitude=40.0, 246 | minlongitude=140.0, 247 | latitude=46.49, 248 | longitude=151.97, 249 | maxradius=1.0, 250 | ) 251 | assert os.path.exists("D20100101000189_20/D20100101000189_20.evt") 252 | shutil.rmtree("D20100101000189_20") 253 | 254 | 255 | def test_get_station_list(client): 256 | stations = client.get_station_list("0101") 257 | assert isinstance(stations, list) 258 | assert len(stations) >= 700 259 | 260 | stations = client.get_station_list("0120") 261 | assert isinstance(stations, list) 262 | assert len(stations) >= 120 263 | 264 | stations = client.get_station_list("0131") 265 | assert isinstance(stations, list) 266 | assert len(stations) >= 250 267 | 268 | 269 | def test_get_allowed_span(client): 270 | assert client._get_allowed_span("0401") == 60 271 | client.select_stations("0101") 272 | assert client._get_allowed_span("0101") == 5 273 | client.select_stations("0101", ["N.AAKH", "N.ABNH"]) 274 | assert client._get_allowed_span("0101") == 60 275 | 276 | 277 | def test_get_selected_stations(client): 278 | client.get_selected_stations("0101") 279 | client.get_selected_stations("0103") 280 | with pytest.raises(ValueError): 281 | client.get_selected_stations("0501") 282 | 283 | 284 | def test_get_win32tools(client): 285 | client._get_win32tools() 286 | os.remove("win32tools.tar.gz") 287 | -------------------------------------------------------------------------------- /tests/test_client_nologin.py: -------------------------------------------------------------------------------- 1 | """Tests with a non-login client.""" 2 | 3 | import pytest 4 | from HinetPy import Client 5 | from HinetPy.client import _parse_code 6 | 7 | 8 | # http://docs.pytest.org/en/latest/fixture.html 9 | # @pytest.fixture is better, but pytest prior 2.10 doesn't support 10 | @pytest.fixture(scope="module") 11 | def client(): 12 | return Client() 13 | 14 | 15 | class TestClientOthersClass: 16 | def test_parse_code(self, client): 17 | assert _parse_code("0101") == ("01", "01", "0") 18 | assert _parse_code("0103A") == ("01", "03A", "0") 19 | assert _parse_code("010503") == ("01", "05", "010503") 20 | assert _parse_code("030201") == ("03", "02", "030201") 21 | 22 | with pytest.raises(ValueError): 23 | _parse_code("01013") 24 | 25 | def test_info(self, client): 26 | client.info() 27 | client.info("0101") 28 | 29 | def test_string(self, client): 30 | print(client) 31 | -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for utils.py. 3 | """ 4 | 5 | from datetime import date, datetime 6 | 7 | import pytest 8 | from HinetPy.utils import ( 9 | check_cmd_exists, 10 | check_package_release, 11 | haversine, 12 | point_inside_box, 13 | point_inside_circular, 14 | split_integer, 15 | to_datetime, 16 | ) 17 | 18 | 19 | def test_split_integer(): 20 | """ 21 | Test split_integer. 22 | """ 23 | assert split_integer(16, 4) == [4, 4, 4, 4] 24 | assert split_integer(15, 4) == [4, 4, 4, 3] 25 | assert split_integer(14, 4) == [4, 4, 3, 3] 26 | assert split_integer(13, 4) == [4, 3, 3, 3] 27 | assert split_integer(12, 4) == [4, 4, 4] 28 | 29 | 30 | def test_point_inside_box(): 31 | """ 32 | Test point_inside_box. 33 | """ 34 | assert point_inside_box(40, 130) 35 | assert point_inside_box(40, 130, 0, 50, 100, 150) 36 | assert point_inside_box(40, 130, maxlatitude=50, minlongitude=100) 37 | assert not point_inside_box(40, 130, 50, 80, 100, 150) 38 | assert not point_inside_box(85, 130, 50, 80, 100, 150) 39 | assert not point_inside_box(60, 170, 50, 80, 100, 150) 40 | with pytest.raises(ValueError): 41 | point_inside_box(40, -130, 50, 80, -150, -140) 42 | 43 | 44 | def test_haversine(): 45 | """ 46 | Test haversine. 47 | """ 48 | assert pytest.approx(haversine(40, 130, 50, 140), 0.01) == 12.22 49 | assert pytest.approx(haversine(-20, 50, 30, 70), 0.01) == 53.58 50 | 51 | 52 | def test_point_inside_circular(): 53 | """ 54 | Test point_inside_circular. 55 | """ 56 | assert point_inside_circular(30, 50, 30, 52, 0, 5) 57 | assert not point_inside_circular(30, 50, 30, 60, 0, 5) 58 | assert not point_inside_circular(30, 50, 30, 60, 30, 50) 59 | 60 | 61 | def test_to_datetime(): 62 | """ 63 | Test to_datetime. 64 | """ 65 | dt = datetime(2010, 2, 3) 66 | assert dt == to_datetime(dt) 67 | 68 | dt1 = date(2010, 2, 3) 69 | dt2 = datetime(2010, 2, 3) 70 | assert dt2 == to_datetime(dt1) 71 | 72 | dt = datetime(2010, 2, 3) 73 | assert dt == to_datetime("20100203") 74 | assert dt == to_datetime("2010-02-03") 75 | 76 | dt = datetime(2001, 2, 3, 4, 5) 77 | assert dt == to_datetime("200102030405") 78 | assert dt == to_datetime("2001-02-03T04:05") 79 | assert dt == to_datetime("2001-02-03 04:05") 80 | 81 | dt = datetime(2001, 2, 3, 4, 5, 6) 82 | assert dt == to_datetime("20010203040506") 83 | assert dt == to_datetime("2001-02-03T04:05:06") 84 | assert dt == to_datetime("2001-02-03 04:05:06") 85 | 86 | dt = datetime(2001, 2, 3, 4, 5, 6, 789000) 87 | assert dt == to_datetime("20010203040506.789") 88 | assert dt == to_datetime("2001-02-03T04:05:06.789") 89 | assert dt == to_datetime("2001-02-03 04:05:06.789") 90 | 91 | with pytest.raises(ValueError): 92 | to_datetime("2001023040506") 93 | 94 | 95 | def test_check_cmd_exists(): 96 | """ 97 | Make sure that all commands exist. 98 | """ 99 | assert check_cmd_exists("catwin32") 100 | assert check_cmd_exists("win2sac_32") 101 | 102 | 103 | def test_check_package_release(): 104 | """ 105 | Check if there is a new release. 106 | """ 107 | assert not check_package_release() 108 | -------------------------------------------------------------------------------- /tests/test_win32.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for win32.py 3 | """ 4 | 5 | import filecmp 6 | import glob 7 | import os 8 | import shutil 9 | import uuid 10 | 11 | import pytest 12 | from HinetPy import Client, win32 13 | 14 | username = os.environ["HINET_USERNAME"] 15 | password = os.environ["HINET_PASSWORD"] 16 | 17 | TESTDIR = "testdir-" + str(uuid.uuid4()) 18 | path = os.path.join(TESTDIR, "data") 19 | data = os.path.join(path, "0101_201701010000_3.cnt") 20 | ctable = os.path.join(path, "0101_20170101.ch") 21 | 22 | 23 | @pytest.fixture(scope="module", autouse=True) 24 | def get_test_data(): 25 | """ 26 | Download the test data used in the tests. 27 | """ 28 | client = Client(username, password) 29 | client.select_stations("0101", ["N.NGUH", "N.NNMH"]) 30 | client.get_continuous_waveform( 31 | "0101", "2017-01-01T00:00", 3, outdir=path, cleanup=False 32 | ) 33 | for file in glob.glob("20170101000?0101VM.cnt"): 34 | os.rename(file, os.path.join(path, file)) 35 | 36 | 37 | def test_extract_sac_defaults(): 38 | """ 39 | Extract SAC files using default settings. 40 | """ 41 | outdir = os.path.join(TESTDIR, "test_extract_sac_defaults") 42 | win32.extract_sac(data, ctable, outdir=outdir) 43 | sac = sorted(glob.glob(os.path.join(outdir, "*.SAC"))) 44 | filelist = [ 45 | "N.NGUH.E.SAC", 46 | "N.NGUH.N.SAC", 47 | "N.NGUH.U.SAC", 48 | "N.NNMH.E.SAC", 49 | "N.NNMH.N.SAC", 50 | "N.NNMH.U.SAC", 51 | ] 52 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 53 | assert sac == sac_to_check 54 | 55 | 56 | def test_extract_sac_without_suffix(): 57 | """ 58 | Extract SAC files without the "SAC" suffix. 59 | """ 60 | outdir = os.path.join(TESTDIR, "test_extract_sac_without_suffix") 61 | win32.extract_sac(data, ctable, suffix="", outdir=outdir) 62 | sac = sorted(glob.glob(os.path.join(outdir, "N.*.[ENU]"))) 63 | filelist = [ 64 | "N.NGUH.E", 65 | "N.NGUH.N", 66 | "N.NGUH.U", 67 | "N.NNMH.E", 68 | "N.NNMH.N", 69 | "N.NNMH.U", 70 | ] 71 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 72 | assert sac == sac_to_check 73 | 74 | 75 | def test_extract_sac_filter_by_ids(): 76 | """ 77 | Extract SAC files by filtering channels using IDs. 78 | """ 79 | outdir = os.path.join(TESTDIR, "test_extract_sac_filter_by_ids") 80 | win32.extract_sac(data, ctable, filter_by_id="3e8?", outdir=outdir) 81 | sac = sorted(glob.glob(os.path.join(outdir, "N.*.SAC"))) 82 | filelist = ["N.NNMH.E.SAC", "N.NNMH.N.SAC", "N.NNMH.U.SAC"] 83 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 84 | assert sac == sac_to_check 85 | 86 | 87 | def test_extract_sac_filter_by_name(): 88 | """ 89 | Extract SAC files by filtering channels using names. 90 | """ 91 | outdir = os.path.join(TESTDIR, "test_extract_sac_filter_by_name") 92 | win32.extract_sac(data, ctable, filter_by_name="N.NG*", outdir=outdir) 93 | sac = sorted(glob.glob(os.path.join(outdir, "N.*.SAC"))) 94 | filelist = ["N.NGUH.E.SAC", "N.NGUH.N.SAC", "N.NGUH.U.SAC"] 95 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 96 | assert sac == sac_to_check 97 | 98 | 99 | def test_extract_sac_filter_by_component(): 100 | """ 101 | Extract SAC files by filtering channels using component names. 102 | """ 103 | outdir = os.path.join(TESTDIR, "test_extract_sac_filter_by_component") 104 | win32.extract_sac(data, ctable, filter_by_component=["N", "E"], outdir=outdir) 105 | sac = sorted(glob.glob(os.path.join(outdir, "N.*.SAC"))) 106 | filelist = ["N.NGUH.E.SAC", "N.NGUH.N.SAC", "N.NNMH.E.SAC", "N.NNMH.N.SAC"] 107 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 108 | assert sac == sac_to_check 109 | 110 | 111 | def test_extract_sac_with_polezero(): 112 | """ 113 | Extract SAC files and polezero files. 114 | """ 115 | outdir = os.path.join(TESTDIR, "test6") 116 | win32.extract_sac( 117 | data, ctable, filter_by_component=["N", "E"], outdir=outdir, with_sacpz=True 118 | ) 119 | sac = sorted(glob.glob(os.path.join(outdir, "N.*.SAC"))) 120 | filelist = ["N.NGUH.E.SAC", "N.NGUH.N.SAC", "N.NNMH.E.SAC", "N.NNMH.N.SAC"] 121 | sac_to_check = [os.path.join(outdir, name) for name in filelist] 122 | assert sac == sac_to_check 123 | 124 | filelist = [ 125 | "N.NGUH.E.SAC_PZ", 126 | "N.NGUH.N.SAC_PZ", 127 | "N.NNMH.E.SAC_PZ", 128 | "N.NNMH.N.SAC_PZ", 129 | ] 130 | pz_to_check = [os.path.join(outdir, name) for name in filelist] 131 | assert pz_to_check == sorted(glob.glob(os.path.join(outdir, "N.*.SAC_PZ"))) 132 | 133 | 134 | def test_extract_sac_none_input(): 135 | """ 136 | Return nothing if the inputs are None. 137 | """ 138 | assert win32.extract_sac(None, None) is None 139 | 140 | 141 | def test_extract_sacpz_default(): 142 | """ 143 | Extract SAC PZ files using default settings. 144 | """ 145 | outdir = os.path.join(TESTDIR, "ch1") 146 | win32.extract_sacpz(ctable, outdir=outdir) 147 | pz_to_check = [ 148 | "N.NNMH.U.SAC_PZ", 149 | "N.NNMH.N.SAC_PZ", 150 | "N.NNMH.E.SAC_PZ", 151 | "N.NGUH.U.SAC_PZ", 152 | "N.NGUH.N.SAC_PZ", 153 | "N.NGUH.E.SAC_PZ", 154 | ] 155 | assert sorted(os.listdir(outdir)) == sorted(pz_to_check) 156 | 157 | 158 | def test_extract_sacpz_custom_suffix(): 159 | """ 160 | Extract SAC PZ files using custom suffix. 161 | """ 162 | outdir = os.path.join(TESTDIR, "ch2") 163 | win32.extract_sacpz(ctable, suffix="SACPZ", outdir=outdir, keep_sensitivity=True) 164 | pz_to_check = [ 165 | "N.NNMH.U.SACPZ", 166 | "N.NNMH.N.SACPZ", 167 | "N.NNMH.E.SACPZ", 168 | "N.NGUH.U.SACPZ", 169 | "N.NGUH.N.SACPZ", 170 | "N.NGUH.E.SACPZ", 171 | ] 172 | assert sorted(os.listdir(outdir)) == sorted(pz_to_check) 173 | 174 | 175 | def test_extract_sacpz_filter_by_component(): 176 | """ 177 | Extract SAC PZ files by filtering channels using components. 178 | """ 179 | outdir = os.path.join(TESTDIR, "ch3") 180 | win32.extract_sacpz(ctable, filter_by_component="U", outdir=outdir) 181 | pz_to_check = ["N.NNMH.U.SAC_PZ", "N.NGUH.U.SAC_PZ"] 182 | assert sorted(os.listdir(outdir)) == sorted(pz_to_check) 183 | 184 | 185 | def test_extract_sacpz_non_input(): 186 | """ 187 | Return None if the input is None. 188 | """ 189 | 190 | 191 | def test_merge_without_sort(): 192 | """ 193 | Merge win32 files without sorting files. 194 | """ 195 | datas = sorted(glob.glob(os.path.join(path, "20170101000?0101VM.cnt"))) 196 | final_to_check = os.path.join(path, "0101_201701010000_3.cnt") 197 | total_data = "test_merge_without_sort.cnt" 198 | 199 | win32.merge(datas, total_data) 200 | assert os.path.exists(total_data) 201 | assert filecmp.cmp(total_data, final_to_check) 202 | os.unlink(total_data) 203 | 204 | 205 | def test_merge_with_sort(): 206 | """ 207 | Merge win32 files that are forced to be sorted. 208 | """ 209 | # datas is unsorted 210 | datas = glob.glob(os.path.join(path, "20170101000?0101VM.cnt"))[::-1] 211 | final_to_check = os.path.join(path, "0101_201701010000_3.cnt") 212 | total_data = "test_merge_with_sort.cnt" 213 | 214 | win32.merge(datas, total_data, force_sort=True) 215 | assert os.path.exists(total_data) 216 | assert filecmp.cmp(total_data, final_to_check) 217 | os.unlink(total_data) 218 | 219 | 220 | def test_merge_with_deep_level_directory(): 221 | """ 222 | Output the merged win32 data to a deep directory. 223 | """ 224 | datas = sorted(glob.glob(os.path.join(path, "20170101000?0101VM.cnt"))) 225 | final_to_check = os.path.join(path, "0101_201701010000_3.cnt") 226 | total_data = "test_merge/with/deep/level/directory/output.cnt" 227 | 228 | win32.merge(datas, total_data) 229 | assert os.path.exists(total_data) 230 | assert filecmp.cmp(total_data, final_to_check) 231 | shutil.rmtree("test_merge") 232 | 233 | 234 | def test_merge_with_wildcard(): 235 | """ 236 | Merge files specified by a wildcard. 237 | """ 238 | final_to_check = os.path.join(path, "0101_201701010000_3.cnt") 239 | total_data = "test_merge_with_wildcard.cnt" 240 | 241 | datas = os.path.join(path, "20170101000?0101VM.cnt") 242 | win32.merge(datas, total_data) 243 | assert os.path.exists(total_data) 244 | assert filecmp.cmp(total_data, final_to_check) 245 | os.unlink(total_data) 246 | 247 | 248 | def test_merge_not_a_valid_wildcard(): 249 | """ 250 | Should raise a warning if the wildcard finds nothing. 251 | """ 252 | datas = os.path.join(path, "not-a-valid-wildcard.cnt") 253 | total_data = "test_merge_not_a_valid_wildcard.cnt" 254 | with pytest.raises(FileNotFoundError): 255 | win32.merge(datas, total_data) 256 | --------------------------------------------------------------------------------